+"""
diff --git a/web/webqtl/annotation/__init__.py b/web/webqtl/annotation/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/base/GeneralObject.py b/web/webqtl/base/GeneralObject.py
new file mode 100755
index 00000000..311c9e22
--- /dev/null
+++ b/web/webqtl/base/GeneralObject.py
@@ -0,0 +1,71 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+class GeneralObject:
+ """
+ Base class to define an Object.
+ a = [Spam(1, 4), Spam(9, 3), Spam(4,6)]
+ a.sort(lambda x, y: cmp(x.eggs, y.eggs))
+ """
+
+ def __init__(self, *args, **kw):
+ self.contents = list(args)
+ for name, value in kw.items():
+ setattr(self, name, value)
+
+ def __setitem__(self, key, value):
+ setattr(self, key, value)
+
+ def __getitem__(self, key):
+ return getattr(self, key)
+
+ def __getattr__(self, key):
+ if key in self.__dict__.keys():
+ return self.__dict__[key]
+ else:
+ return eval("self.__dict__.%s" % key)
+
+ def __len__(self):
+ return len(self.__dict__) - 1
+
+ def __str__(self):
+ s = ''
+ for key in self.__dict__.keys():
+ if key != 'contents':
+ s += '%s = %s\n' % (key,self.__dict__[key])
+ return s
+
+ def __repr__(self):
+ s = ''
+ for key in self.__dict__.keys():
+ s += '%s = %s\n' % (key,self.__dict__[key])
+ return s
+
+ def __cmp__(self,other):
+ return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys()))
+
+
+
diff --git a/web/webqtl/base/__init__.py b/web/webqtl/base/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/base/admin.py b/web/webqtl/base/admin.py
new file mode 100755
index 00000000..a04df2da
--- /dev/null
+++ b/web/webqtl/base/admin.py
@@ -0,0 +1,88 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+
+
+
+
+#XZ, 04/02/2009: we should put this into database.
+
+
+###LIST of databases used into gene name query
+
+
+ADMIN_search_dbs = {
+ 'rat': {'PERITONEAL FAT': ['FT_2A_0605_Rz'],
+ 'KIDNEY': ['KI_2A_0405_Rz'],
+ 'ADRENAL GLAND': ['HXB_Adrenal_1208'],
+ 'HEART': ['HXB_Heart_1208']
+ },
+ 'mouse': {'CEREBELLUM': ['CB_M_0305_R'],
+ 'STRIATUM': ['SA_M2_0905_R', 'SA_M2_0405_RC', 'UTHSC_1107_RankInv', 'Striatum_Exon_0209'],
+ 'HIPPOCAMPUS': ['HC_M2_0606_R', 'UMUTAffyExon_0209_RMA'],
+ 'WHOLE BRAIN': ['BR_M2_1106_R', 'IBR_M_0106_R', 'BRF2_M_0805_R', 'UCLA_BHF2_BRAIN_0605'],
+ 'LIVER': ['LV_G_0106_B', 'UCLA_BHF2_LIVER_0605'],
+ 'EYE': ['Eye_M2_0908_R'],
+ 'HEMATOPOIETIC STEM CELLS': ['HC_U_0304_R'],
+ 'KIDNEY': ['MA_M2_0806_R'],
+ 'MAMMARY TUMORS': ['MA_M_0704_R', 'NCI_Agil_Mam_Tum_RMA_0409'],
+ 'PREFRONTAL CORTEX': ['VCUSal_1206_R'],
+ 'SPLEEN': ['IoP_SPL_RMA_0509'],
+ 'NUCLEUS ACCUMBENS': ['VCUSalo_1007_R'],
+ 'NEOCORTEX': ['HQFNeoc_0208_RankInv'],
+ 'ADIPOSE': ['UCLA_BHF2_ADIPOSE_0605'],
+ 'RETINA': ['Illum_Retina_BXD_RankInv0410']
+ },
+ 'human': {
+ 'LYMPHOBLAST B CELL': ['Human_1008', 'UT_CEPH_RankInv0909'],
+ 'WHOLE BRAIN': ['GSE5281_F_RMA0709', 'GSE15222_F_RI_0409']
+ }
+ }
+
+
+###LIST of tissue alias
+
+ADMIN_tissue_alias = {'CEREBELLUM': ['Cb'],
+ 'STRIATUM': ['Str'],
+ 'HIPPOCAMPUS': ['Hip'],
+ 'WHOLE BRAIN': ['Brn'],
+ 'LIVER': ['Liv'],
+ 'EYE': ['Eye'],
+ 'PERITONEAL FAT': ['Fat'],
+ 'HEMATOPOIETIC STEM CELLS': ['Hsc'],
+ 'KIDNEY': ['Kid'],
+ 'ADRENAL GLAND': ['Adr'],
+ 'HEART': ['Hea'],
+ 'MAMMARY TUMORS': ['Mam'],
+ 'PREFRONTAL CORTEX': ['Pfc'],
+ 'SPLEEN': ['Spl'],
+ 'NUCLEUS ACCUMBENS': ['Nac'],
+ 'NEOCORTEX': ['Ctx'],
+ 'ADIPOSE': ['Wfat'],
+ 'RETINA': ['Ret']
+ }
+
+
diff --git a/web/webqtl/base/cgiData.py b/web/webqtl/base/cgiData.py
new file mode 100755
index 00000000..57416060
--- /dev/null
+++ b/web/webqtl/base/cgiData.py
@@ -0,0 +1,70 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#########################################
+#convert Field storage object to Dict object
+#in order to be able to saved into a session file
+#########################################
+
+class cgiData(dict):
+ '''convert Field storage object to Dict object
+ Filed storage object cannot be properly dumped
+ '''
+
+ def __init__(self, field_storage=None):
+
+ if not field_storage:
+ field_storage={}
+
+ for key in field_storage.keys():
+ temp = field_storage.getlist(key)
+ if len(temp) > 1:
+ temp = map(self.toValue, temp)
+ elif len(temp) == 1:
+ temp = self.toValue(temp[0])
+ else:
+ temp = None
+ self[key]= temp
+
+ def toValue(self, obj):
+ '''fieldstorge returns different type of objects, \
+ need to convert to string or None'''
+ try:
+ return obj.value
+ except:
+ return ""
+
+ def getvalue(self, k, default= None):
+ try:
+ return self[k]
+ except:
+ return default
+
+ getfirst = getvalue
+
+
+
+
diff --git a/web/webqtl/base/cookieData.py b/web/webqtl/base/cookieData.py
new file mode 100755
index 00000000..4b7c9046
--- /dev/null
+++ b/web/webqtl/base/cookieData.py
@@ -0,0 +1,52 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#########################################
+#convert mod_python object to Dict object
+#in order to be able to be pickled
+#########################################
+
+class cookieData(dict):
+ 'convert mod python Cookie object to Dict object'
+
+ def __init__(self, cookies=None):
+
+ if not cookies:
+ cookies={}
+
+ for key in cookies.keys():
+ self[key.lower()]= cookies[key].value
+
+ def getvalue(self, k, default= None):
+ try:
+ return self[k.lower()]
+ except:
+ return default
+
+ getfirst = getvalue
+
+
+
diff --git a/web/webqtl/base/footer.py b/web/webqtl/base/footer.py
new file mode 100755
index 00000000..6f92fdf8
--- /dev/null
+++ b/web/webqtl/base/footer.py
@@ -0,0 +1,6 @@
+import webqtlConfig
+
+footer_html = open(webqtlConfig.HTMLPATH + 'footer.html', 'r').read()
+footer = footer_html.replace('%"','%%"')
+
+footer_string = footer.replace('', '%s')
diff --git a/web/webqtl/base/header.py b/web/webqtl/base/header.py
new file mode 100755
index 00000000..b6136b51
--- /dev/null
+++ b/web/webqtl/base/header.py
@@ -0,0 +1,6 @@
+import webqtlConfig
+
+header_string = open(webqtlConfig.HTMLPATH + 'header.html', 'r').read()
+header_string = header_string.replace("\\'", "'")
+header_string = header_string.replace('%"','%%"')
+header_string = header_string.replace('', '%s')
\ No newline at end of file
diff --git a/web/webqtl/base/indexBody.py b/web/webqtl/base/indexBody.py
new file mode 100755
index 00000000..aa67dffa
--- /dev/null
+++ b/web/webqtl/base/indexBody.py
@@ -0,0 +1,290 @@
+index_body_string = """
+
+
+
+ You can also use advanced commands. Copy these simple examples
+ into the Get Any or Combined search fields:
+
+
+
POSITION=(chr1 25 30) finds genes, markers, or transcripts on chromosome 1 between 25 and 30 Mb.
+
+
MEAN=(15 16) LRS=(23 46) in the Combined field finds highly expressed genes (15 to 16 log2 units) AND with peak LRS linkage between 23 and 46.
+
+
+
RIF=mitochondrial searches RNA databases for GeneRIF links.
+
+
WIKI=nicotine searches GeneWiki for genes that you or other users have annotated with the word nicotine.
+
+
GO:0045202 searches for synapse-associated genes listed in the Gene Ontology.
+
+
+
GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10) in Combined finds synapse-associated genes with cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores between 9 and 999.
+
+
RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10) in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS scores between 9 and 999.
+
+
+
GeneNetwork's Time Machine links to earlier versions that correspond to specific publication dates.
+
+
+
+
+
+
+"""
diff --git a/web/webqtl/base/myCookie.py b/web/webqtl/base/myCookie.py
new file mode 100755
index 00000000..db5320df
--- /dev/null
+++ b/web/webqtl/base/myCookie.py
@@ -0,0 +1,55 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#########################################
+## python cookie and mod python cookie are
+## not compatible
+#########################################
+
+class myCookie(dict):
+ 'define my own cookie'
+
+ def __init__(self, name="", value="", expire = None, path="/"):
+ self['name']= name
+ self['value']= value
+ self['expire']= expire
+ self['path']= path
+
+ def __getattr__(self, key):
+ if key in self.keys():
+ return self[key]
+ else:
+ return None
+
+ def __nonzero__ (self):
+ if self['name']:
+ return 1
+ else:
+ return 0
+
+
+
+
diff --git a/web/webqtl/base/sessionData.py b/web/webqtl/base/sessionData.py
new file mode 100755
index 00000000..01555f87
--- /dev/null
+++ b/web/webqtl/base/sessionData.py
@@ -0,0 +1,53 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#########################################
+#convert mod_python object to Dict object
+#in order to be able to be pickled
+#########################################
+
+class sessionData(dict):
+ 'convert mod python Session object to Dict object'
+
+ def __init__(self, mod_python_session=None):
+
+ if not mod_python_session:
+ mod_python_session = {}
+
+ for key in mod_python_session.keys():
+ self[key]= mod_python_session[key]
+
+
+ def getvalue(self, k, default= None):
+ try:
+ return self[k]
+ except:
+ return default
+
+ getfirst = getvalue
+
+
+
diff --git a/web/webqtl/base/template.py b/web/webqtl/base/template.py
new file mode 100644
index 00000000..85bd86df
--- /dev/null
+++ b/web/webqtl/base/template.py
@@ -0,0 +1,123 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+template = """
+
+
+
+
+%s
+
+
+
+
+
+
+
+%s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%s
+
+
+
+
+%s
+
+
+
+
+ %s
+
+
+
+
+
+
+
+
+ %s
+
+
+
+
+
+
+
+
+
+
%s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"""
diff --git a/web/webqtl/base/templatePage.py b/web/webqtl/base/templatePage.py
new file mode 100644
index 00000000..4dece24a
--- /dev/null
+++ b/web/webqtl/base/templatePage.py
@@ -0,0 +1,222 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#templatePage.py
+#
+#--Genenetwork generates a lot of pages; this file is the generic version of them, defining routines they all use.
+#
+#Classes:
+#templatePage
+#
+#Functions (of templatePage):
+#__init__(...) -- class constructor, allows a more specific template to be used in addition to templatePage
+#__str__(self) -- returns the object's elements as a tuple
+#__del__(self) -- closes the current connection to MySQL, if there is one
+#write -- explained below
+#writefile -- explained below
+#openMysql(self) -- opens a MySQL connection and stores the resulting cursor in the object's cursor variable
+#updMysql(self) -- same as openMysql
+#error -- explained below
+#session -- explained below
+
+
+import socket
+import time
+import shutil
+import MySQLdb
+import os
+
+from htmlgen import HTMLgen2 as HT
+
+import template
+import webqtlConfig
+import header
+import footer
+from utility import webqtlUtil
+
+
+
+class templatePage:
+
+ contents = ['title','basehref','js1','js2', 'layer', 'header', 'body', 'footer']
+
+ # you can pass in another template here if you want
+ def __init__(self, fd=None, template=template.template):
+
+ # initiate dictionary
+ self.starttime = time.time()
+ self.dict = {}
+ self.template = template
+
+ for item in self.contents:
+ self.dict[item] = ""
+
+ self.dict['basehref'] = "" #webqtlConfig.BASEHREF
+ self.cursor = None
+
+ self.cookie = [] #XZ: list to hold cookies (myCookie object) being changed
+ self.content_type = 'text/html'
+ self.content_disposition = ''
+ self.redirection = ''
+ self.debug = ''
+ self.attachment = ''
+
+ #XZ: Holding data (new data or existing data being changed) that should be saved to session. The data must be picklable!!!
+ self.session_data_changed = {}
+
+ self.userName = 'Guest'
+ self.privilege = 'guest'
+ if fd.input_session_data.has_key('user'):
+ self.userName = fd.input_session_data['user']
+ if fd.input_session_data.has_key('privilege'):
+ self.privilege = fd.input_session_data['privilege']
+
+ def __str__(self):
+
+ #XZ: default setting
+ thisUserName = self.userName
+ thisPrivilege = self.privilege
+ #XZ: user may just go through login or logoff page
+ if self.session_data_changed.has_key('user'):
+ thisUserName = self.session_data_changed['user']
+ if self.session_data_changed.has_key('privilege'):
+ thisPrivilege = self.session_data_changed['privilege']
+
+ if thisUserName == 'Guest':
+ userInfo = 'Welcome! Login'
+ else:
+ userInfo = 'Hi, %s! Logout' % thisUserName
+
+ reload(header)
+ self.dict['header'] = header.header_string % userInfo
+
+ serverInfo = "It took %2.3f second(s) for %s to generate this page" % (time.time()-self.starttime, socket.getfqdn())
+ reload(footer)
+ self.dict['footer'] = footer.footer_string % serverInfo
+
+ slist = []
+ for item in self.contents:
+ slist.append(self.dict[item])
+ return self.template % tuple(slist)
+
+
+ def __del__(self):
+ if self.cursor:
+ self.cursor.close()
+
+ def write(self):
+ 'return string representation of this object'
+
+ if self.cursor:
+ self.cursor.close()
+
+ return str(self)
+
+ def writeFile(self, filename):
+ 'save string representation of this object into a file'
+ if self.cursor:
+ self.cursor.close()
+
+ try:
+ 'it could take a long time to generate the file, save to .tmp first'
+ fp = open(os.path.join(webqtlConfig.TMPDIR, filename+'.tmp'), 'wb')
+ fp.write(str(self))
+ fp.close()
+ path_tmp = os.path.join(webqtlConfig.TMPDIR, filename+'.tmp')
+ path_html = os.path.join(webqtlConfig.TMPDIR, filename)
+ shutil.move(path_tmp,path_html)
+ except:
+ pass
+
+ def openMysql(self):
+ try:
+ self.con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, \
+ user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD)
+ self.cursor = self.con.cursor()
+ return 1
+ except:
+ heading = "Connect MySQL Server"
+ detail = ["Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_SERVER+"':100061. \
+ The server may be down at this time"]
+ self.error(heading=heading,detail=detail,error="Error 2003")
+ return 0
+
+ def updMysql(self):
+ try:
+ self.con = MySQLdb.Connect(db=webqtlConfig.DB_UPDNAME,host=webqtlConfig.MYSQL_UPDSERVER, \
+ user=webqtlConfig.DB_UPDUSER,passwd=webqtlConfig.DB_UPDPASSWD)
+ self.cursor = self.con.cursor()
+ return 1
+ except:
+ heading = "Connect MySQL Server"
+ detail = ["update: Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_UPDSERVER+"':100061. \
+ The server may be down at this time "]
+ self.error(heading=heading,detail=detail,error="Error 2003")
+ return 0
+
+ def error(self,heading="",intro=[],detail=[],title="Error",error="Error"):
+ 'generating a WebQTL style error page'
+ Heading = HT.Paragraph(heading)
+ Heading.__setattr__("class","title")
+
+ Intro = HT.Blockquote()
+ if intro:
+ for item in intro:
+ Intro.append(item)
+ else:
+ Intro.append(HT.Strong('Sorry!'),' Error occurred while processing\
+ your request.', HT.P(),'The nature of the error generated is as\
+ follows:')
+
+ Detail = HT.Blockquote()
+ Detail.append(HT.Span("%s : " % error,Class="fwb cr"))
+ if detail:
+ Detail2 = HT.Blockquote()
+ for item in detail:
+ Detail2.append(item)
+ Detail.append(HT.Italic(Detail2))
+
+ #Detail.__setattr__("class","subtitle")
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top")
+ TD_LR.append(Heading,Intro,Detail)
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = title
+
+ def session(self,mytitle="",myHeading=""):
+ 'generate a auto-refreshing temporary html file(waiting page)'
+ self.filename = webqtlUtil.generate_session()
+ self.dict['title'] = mytitle
+ self.dict['basehref'] = webqtlConfig.REFRESHSTR % (webqtlConfig.CGIDIR, self.filename) + "" #webqtlConfig.BASEHREF
+
+ TD_LR = HT.TD(align="center", valign="middle", height=200,width="100%", bgColor='#eeeeee')
+ Heading = HT.Paragraph(myHeading, Class="fwb fs16 cr")
+ # NL, 07/27/2010. variable 'PROGRESSBAR' has been moved from templatePage.py to webqtlUtil.py;
+ TD_LR.append(Heading, HT.BR(), webqtlUtil.PROGRESSBAR)
+ self.dict['body'] = TD_LR
+ self.writeFile(self.filename + '.html')
+ return self.filename
+
+
diff --git a/web/webqtl/base/webqtlCaseData.py b/web/webqtl/base/webqtlCaseData.py
new file mode 100755
index 00000000..4df32ca4
--- /dev/null
+++ b/web/webqtl/base/webqtlCaseData.py
@@ -0,0 +1,54 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+class webqtlCaseData:
+ """
+ one case data in one trait
+ """
+
+ val = None #Trait Value
+ var = None #Trait Variance
+ N = None #Number of individuals
+
+ def __init__(self, val=val, var=var, N=N):
+ self.val = val
+ self.var = var
+ self.N = N
+
+ def __str__(self):
+ str = ""
+ if self.val != None:
+ str += "value=%2.3f" % self.val
+ if self.var != None:
+ str += " variance=%2.3f" % self.var
+ if self.N != None:
+ str += " ndata=%d" % self.N
+ return str
+
+ __repr__ = __str__
+
+
+
diff --git a/web/webqtl/base/webqtlConfig.py b/web/webqtl/base/webqtlConfig.py
new file mode 100755
index 00000000..87e2f3d0
--- /dev/null
+++ b/web/webqtl/base/webqtlConfig.py
@@ -0,0 +1,73 @@
+from webqtlConfigLocal import *
+#########################################'
+# Environment Variables - public
+#########################################
+
+#Debug Level
+#1 for debug, mod python will reload import each time
+DEBUG = 1
+
+#USER privilege
+USERDICT = {'guest':1,'user':2, 'admin':3, 'root':4}
+
+#minimum number of informative strains
+KMININFORMATIVE = 5
+
+#maximum number of traits for interval mapping
+MULTIPLEMAPPINGLIMIT = 11
+
+#maximum number of traits for correlation
+MAXCORR = 100
+
+#Daily download limit from one IP
+DAILYMAXIMUM = 1000
+
+#maximum LRS value
+MAXLRS = 460.0
+
+#temporary data life span
+MAXLIFE = 86400
+
+#MINIMUM Database public value
+PUBLICTHRESH = 0
+
+#NBCI address
+NCBI_LOCUSID = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s"
+UCSC_REFSEQ = "http://genome.cse.ucsc.edu/cgi-bin/hgGene?db=%s&hgg_gene=%s&hgg_chrom=chr%s&hgg_start=%s&hgg_end=%s"
+GENBANK_ID = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=Nucleotide&cmd=search&doptcmdl=DocSum&term=%s"
+OMIM_ID = "http://www.ncbi.nlm.nih.gov/omim/%s"
+UNIGEN_ID = "http://www.ncbi.nlm.nih.gov/UniGene/clust.cgi?ORG=%s&CID=%s"
+HOMOLOGENE_ID = "http://www.ncbi.nlm.nih.gov/sites/entrez?Db=homologene&Cmd=DetailsSearch&Term=%s"
+PUBMEDLINK_URL = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=%s&dopt=Abstract"
+UCSC_POS = "http://genome.ucsc.edu/cgi-bin/hgTracks?clade=mammal&org=%s&db=%s&position=chr%s:%s-%s&pix=800&Submit=submit"
+UCSC_BLAT = 'http://genome.ucsc.edu/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s'
+UTHSC_BLAT = 'http://ucscbrowser.genenetwork.org/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s'
+UCSC_GENOME = "http://genome.ucsc.edu/cgi-bin/hgTracks?db=%s&position=chr%s:%d-%d&hgt.customText=http://web2qtl.utmem.edu:88/snp/chr%s"
+ENSEMBLE_BLAT = 'http://www.ensembl.org/Mus_musculus/featureview?type=AffyProbe&id=%s'
+DBSNP = 'http://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?type=rs&rs=%s'
+UCSC_RUDI_TRACK_URL = " http://genome.cse.ucsc.edu/cgi-bin/hgTracks?org=%s&db=%s&hgt.customText=http://gbic.biol.rug.nl/~ralberts/tracks/%s/%s"
+GENOMEBROWSER_URL="http://ucscbrowser.genenetwork.org/cgi-bin/hgTracks?clade=mammal&org=Mouse&db=mm9&position=%s&hgt.suggest=&pix=800&Submit=submit"
+ENSEMBLETRANSCRIPT_URL="http://useast.ensembl.org/Mus_musculus/Lucene/Details?species=Mus_musculus;idx=Transcript;end=1;q=%s"
+
+SECUREDIR = GNROOT + 'secure/'
+COMMON_LIB = GNROOT + 'support/admin'
+HTMLPATH = GNROOT + 'web/'
+IMGDIR = HTMLPATH +'image/'
+IMAGESPATH = HTMLPATH + 'images/'
+UPLOADPATH = IMAGESPATH + 'upload/'
+TMPDIR = HTMLPATH +'tmp/'
+GENODIR = HTMLPATH + 'genotypes/'
+GENO_ARCHIVE_DIR = GENODIR + 'archive/'
+TEXTDIR = HTMLPATH + 'ProbeSetFreeze_DataMatrix/'
+CMDLINEDIR = HTMLPATH + 'webqtl/cmdLine/'
+ChangableHtmlPath = GNROOT + 'web/'
+
+SITENAME = 'GN'
+PORTADDR = "http://132.192.47.32"
+BASEHREF = ''
+INFOPAGEHREF = '/dbdoc/%s.html'
+GLOSSARYFILE = "/glossary.html"
+CGIDIR = '/webqtl/' #XZ: The variable name 'CGIDIR' should be changed to 'PYTHONDIR'
+SCRIPTFILE = 'main.py'
+REFRESHSTR = ''
+REFRESHDIR = '%s' + SCRIPTFILE +'?sid=%s'
diff --git a/web/webqtl/base/webqtlConfigLocal.py b/web/webqtl/base/webqtlConfigLocal.py
new file mode 100755
index 00000000..0c95fe7b
--- /dev/null
+++ b/web/webqtl/base/webqtlConfigLocal.py
@@ -0,0 +1,19 @@
+#########################################'
+# Environment Variables - private
+#########################################
+
+MYSQL_SERVER = 'localhost'
+DB_NAME = 'db_webqtl'
+DB_USER = 'webqtlupd'
+DB_PASSWD = 'webqtl'
+
+MYSQL_UPDSERVER = 'localhost'
+DB_UPDNAME = 'db_webqtl'
+DB_UPDUSER = 'webqtlupd'
+DB_UPDPASSWD = 'webqtl'
+
+GNROOT = '/gnshare/gn/'
+PythonPath = '/usr/bin/python'
+PIDDLE_FONT_PATH = '/usr/lib/python2.4/site-packages/piddle/truetypefonts/'
+
+TEXTUI=0 # This is to protect GN production server. If set to 0, no text UI is allowed.
diff --git a/web/webqtl/base/webqtlDataset.py b/web/webqtl/base/webqtlDataset.py
new file mode 100755
index 00000000..da1b8601
--- /dev/null
+++ b/web/webqtl/base/webqtlDataset.py
@@ -0,0 +1,160 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from htmlgen import HTMLgen2 as HT
+
+import webqtlConfig
+
+
+
+class webqtlDataset:
+ """
+ Database class defines a database in webqtl, can be either Microarray,
+ Published phenotype, genotype, or user input database(temp)
+ """
+
+ def __init__(self, dbName, cursor=None):
+
+ assert dbName
+ self.id = 0
+ self.name = ''
+ self.type = ''
+ self.riset = ''
+ self.cursor = cursor
+
+ #temporary storage
+ if dbName.find('Temp') >= 0:
+ self.searchfield = ['name','description']
+ self.disfield = ['name','description']
+ self.type = 'Temp'
+ self.id = 1
+ self.fullname = 'Temporary Storage'
+ self.shortname = 'Temp'
+ elif dbName.find('Publish') >= 0:
+ self.searchfield = ['name','post_publication_description','abstract','title','authors']
+ self.disfield = ['name','pubmed_id',
+ 'pre_publication_description', 'post_publication_description', 'original_description',
+ 'pre_publication_abbreviation', 'post_publication_abbreviation',
+ 'lab_code', 'submitter', 'owner', 'authorized_users',
+ 'authors','title','abstract', 'journal','volume','pages','month',
+ 'year','sequence', 'units', 'comments']
+ self.type = 'Publish'
+ elif dbName.find('Geno') >= 0:
+ self.searchfield = ['name','chr']
+ self.disfield = ['name','chr','mb', 'source2', 'sequence']
+ self.type = 'Geno'
+ else: #ProbeSet
+ self.searchfield = ['name','description','probe_target_description',
+ 'symbol','alias','genbankid','unigeneid','omim',
+ 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score']
+ self.disfield = ['name','symbol','description','probe_target_description',
+ 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim',
+ 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments',
+ 'strand_probe','strand_gene','probe_set_target_region',
+ 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start',
+ 'probe_set_blat_mb_end', 'probe_set_strand',
+ 'probe_set_note_by_rw', 'flag']
+ self.type = 'ProbeSet'
+ self.name = dbName
+ if self.cursor and self.id == 0:
+ self.retrieveName()
+
+ def __str__(self):
+ return self.name
+
+ __repr__ = __str__
+
+
+ def getRISet(self):
+ assert self.cursor
+ if self.type == 'Publish':
+ query = '''
+ SELECT
+ InbredSet.Name, InbredSet.Id
+ FROM
+ InbredSet, PublishFreeze
+ WHERE
+ PublishFreeze.InbredSetId = InbredSet.Id AND
+ PublishFreeze.Name = "%s"
+ ''' % self.name
+ elif self.type == 'Geno':
+ query = '''
+ SELECT
+ InbredSet.Name, InbredSet.Id
+ FROM
+ InbredSet, GenoFreeze
+ WHERE
+ GenoFreeze.InbredSetId = InbredSet.Id AND
+ GenoFreeze.Name = "%s"
+ ''' % self.name
+ elif self.type == 'ProbeSet':
+ query = '''
+ SELECT
+ InbredSet.Name, InbredSet.Id
+ FROM
+ InbredSet, ProbeSetFreeze, ProbeFreeze
+ WHERE
+ ProbeFreeze.InbredSetId = InbredSet.Id AND
+ ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND
+ ProbeSetFreeze.Name = "%s"
+ ''' % self.name
+ else:
+ return ""
+ self.cursor.execute(query)
+ RISet, RIID = self.cursor.fetchone()
+ if RISet == 'BXD300':
+ RISet = "BXD"
+ self.riset = RISet
+ self.risetid = RIID
+ return RISet
+
+
+ def retrieveName(self):
+ assert self.id == 0 and self.cursor
+ query = '''
+ SELECT
+ Id, Name, FullName, ShortName
+ FROM
+ %sFreeze
+ WHERE
+ public > %d AND
+ (Name = "%s" OR FullName = "%s" OR ShortName = "%s")
+ '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name)
+ try:
+ self.cursor.execute(query)
+ self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone()
+ except:
+ raise KeyError, `self.name`+' doesn\'t exist.'
+
+
+ def genHTML(self, Class='c0dd'):
+ return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class),
+ url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank")
+
+
+
+
+
diff --git a/web/webqtl/base/webqtlFormData.py b/web/webqtl/base/webqtlFormData.py
new file mode 100755
index 00000000..84e41cae
--- /dev/null
+++ b/web/webqtl/base/webqtlFormData.py
@@ -0,0 +1,289 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from mod_python import Cookie
+import string
+import os
+
+import reaper
+
+import webqtlConfig
+import cookieData
+import sessionData
+from cgiData import cgiData
+from webqtlCaseData import webqtlCaseData
+from utility import webqtlUtil
+
+
+
+class webqtlFormData:
+ 'Represents data from a WebQTL form page, needed to generate the next page'
+ attrs = ('formID','RISet','genotype','strainlist','allstrainlist',
+ 'suggestive','significance','submitID','identification', 'enablevariance',
+ 'nperm','nboot','email','incparentsf1','genotype_1','genotype_2','traitInfo')
+
+ #XZ: Attention! All attribute values must be picklable!
+
+ def __init__(self, req = None, mod_python_session=None, FieldStorage_formdata=None):
+
+ for item in self.attrs:
+ setattr(self,item, None)
+
+ try:
+ self.remote_ip = req.connection.remote_ip
+ except:
+ self.remote_ip = '1.2.3.4'
+
+ if req and req.headers_in.has_key('referer'):
+ self.refURL = req.headers_in['referer']
+ else:
+ self.refURL = None
+
+
+ self.cookies = cookieData.cookieData(Cookie.get_cookies(req)) #XZ: dictionary type. To hold values transfered from mod_python Cookie.
+
+ #XZ: dictionary type. To hold values transfered from mod_python Session object. We assume that it is always picklable.
+ self.input_session_data = sessionData.sessionData( mod_python_session )
+
+ #XZ: FieldStorage_formdata may contain item that can't be pickled. Must convert to picklable data.
+ self.formdata = cgiData( FieldStorage_formdata )
+
+ #get Form ID
+ self.formID = self.formdata.getfirst('FormID')
+
+ #get rest of the attributes
+ if self.formID:
+ for item in self.attrs:
+ value = self.formdata.getfirst(item)
+ if value != None:
+ setattr(self,item,string.strip(value))
+
+ self.ppolar = ""
+ self.mpolar = ""
+ if self.RISet:
+ try:
+ # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py;
+ f1, f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.RISet]
+ except:
+ f1 = f12 = self.mpolar = self.ppolar = None
+
+ try:
+ self.nperm = int(self.nperm)
+ self.nboot = int(self.nboot)
+ except:
+ self.nperm = 2000 #XZ: Rob asked to change the default value to 2000
+ self.nboot = 2000 #XZ: Rob asked to change the default value to 2000
+
+ if self.allstrainlist:
+ self.allstrainlist = map(string.strip, string.split(self.allstrainlist))
+ #self.readGenotype()
+ #self.readData()
+
+ if self.RISet == 'BXD300':
+ self.RISet = 'BXD'
+ else:
+ pass
+
+ def __str__(self):
+ rstr = ''
+ for item in self.attrs:
+ if item != 'genotype':
+ rstr += '%s:%s\n' % (item,str(getattr(self,item)))
+ return rstr
+
+
+ def readGenotype(self):
+ 'read genotype from .geno file'
+ if self.RISet == 'BXD300':
+ self.RISet = 'BXD'
+ else:
+ pass
+ assert self.RISet
+ #genotype_1 is Dataset Object without parents and f1
+ #genotype_2 is Dataset Object with parents and f1 (not for intercross)
+ self.genotype_1 = reaper.Dataset()
+ self.genotype_1.read(os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno'))
+ try:
+ # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py;
+ _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet]
+ except:
+ _f1 = _f12 = _mat = _pat = None
+
+ self.genotype_2 =self.genotype_1
+ if self.genotype_1.type == "riset" and _mat and _pat:
+ self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1)
+
+ #determine default genotype object
+ if self.incparentsf1 and self.genotype_1.type != "intercross":
+ self.genotype = self.genotype_2
+ else:
+ self.incparentsf1 = 0
+ self.genotype = self.genotype_1
+ self.strainlist = list(self.genotype.prgy)
+ self.f1list = self.parlist = []
+ if _f1 and _f12:
+ self.f1list = [_f1, _f12]
+ if _mat and _pat:
+ self.parlist = [_mat, _pat]
+
+ def readData(self, strainlst=[], incf1=[]):
+ 'read user input data or from trait data and analysis form'
+
+ if not self.genotype:
+ self.readGenotype()
+ if not strainlst:
+ if incf1:
+ strainlst = self.f1list + self.strainlist
+ else:
+ strainlst = self.strainlist
+
+
+ traitfiledata = self.formdata.getfirst('traitfile')
+ traitpastedata = self.formdata.getfirst('traitpaste')
+ variancefiledata = self.formdata.getfirst('variancefile')
+ variancepastedata = self.formdata.getfirst('variancepaste')
+ Nfiledata = self.formdata.getfirst('Nfile')
+
+
+ if traitfiledata:
+ tt = string.split(traitfiledata)
+ vals = map(webqtlUtil.StringAsFloat, tt)
+ elif traitpastedata:
+ tt = string.split(traitpastedata)
+ vals = map(webqtlUtil.StringAsFloat, tt)
+ else:
+ vals = map(self.FormDataAsFloat, strainlst)
+
+ if len(vals) < len(strainlst):
+ vals += [None]*(len(strainlst) - len(vals))
+ elif len(vals) > len(strainlst):
+ vals = vals[:len(strainlst)]
+ else:
+ pass
+
+
+ if variancefiledata:
+ tt = string.split(variancefiledata)
+ vars = map(webqtlUtil.StringAsFloat, tt)
+ elif variancepastedata:
+ tt = string.split(variancepastedata)
+ vars = map(webqtlUtil.StringAsFloat, tt)
+ else:
+ vars = map(self.FormVarianceAsFloat, strainlst)
+
+ if len(vars) < len(strainlst):
+ vars += [None]*(len(strainlst) - len(vars))
+ elif len(vars) > len(strainlst):
+ vars = vars[:len(strainlst)]
+ else:
+ pass
+
+ if Nfiledata:
+ tt = string.split(Nfiledata)
+ nstrains = map(webqtlUtil.IntAsFloat, tt)
+ if len(nstrains) < len(strainlst):
+ nstrains += [None]*(len(strainlst) - len(nstrains))
+ else:
+ nstrains = map(self.FormNAsFloat, strainlst)
+
+ ##vals, vars, nstrains is obsolete
+ self.allTraitData = {}
+ for i, _strain in enumerate(strainlst):
+ if vals[i] != None:
+ self.allTraitData[_strain] = webqtlCaseData(vals[i], vars[i], nstrains[i])
+
+
+
+ def informativeStrains(self, strainlst=[], incVars = 0):
+ '''if readData was called, use this to output the informative strains
+ (strain with values)'''
+ if not strainlst:
+ strainlst = self.strainlist
+ strains = []
+ vals = []
+ vars = []
+ for _strain in strainlst:
+ if self.allTraitData.has_key(_strain):
+ _val, _var = self.allTraitData[_strain].val, self.allTraitData[_strain].var
+ if _val != None:
+ if incVars:
+ if _var != None:
+ strains.append(_strain)
+ vals.append(_val)
+ vars.append(_var)
+ else:
+ strains.append(_strain)
+ vals.append(_val)
+ vars.append(None)
+ return strains, vals, vars, len(strains)
+
+
+
+ def FormDataAsFloat(self, key):
+ try:
+ return float(self.formdata.getfirst(key))
+ except:
+ return None
+
+
+ def FormVarianceAsFloat(self, key):
+ try:
+ return float(self.formdata.getfirst('V' + key))
+ except:
+ return None
+
+ def FormNAsFloat(self, key):
+ try:
+ return int(self.formdata.getfirst('N' + key))
+ except:
+ return None
+
+ def Sample(self):
+ 'Create some dummy data for testing'
+ self.RISet = 'BXD'
+ self.incparentsf1 = 'on'
+ #self.display = 9.2
+ #self.significance = 16.1
+ self.readGenotype()
+ self.identification = 'BXD : Coat color example by Lu Lu, et al'
+ #self.readGenotype()
+ #self.genotype.ReadMM('AXBXAforQTL')
+ #self.strainlist = map((lambda x, y='': '%s%s' % (y,x)), self.genotype.prgy)
+ #self.strainlist.sort()
+ self.allTraitData = {'BXD29': webqtlCaseData(3), 'BXD28': webqtlCaseData(2),
+ 'BXD25': webqtlCaseData(2), 'BXD24': webqtlCaseData(2), 'BXD27': webqtlCaseData(2),
+ 'BXD21': webqtlCaseData(1), 'BXD20': webqtlCaseData(4), 'BXD23': webqtlCaseData(4),
+ 'BXD22': webqtlCaseData(3), 'BXD14': webqtlCaseData(4), 'BXD15': webqtlCaseData(2),
+ 'BXD16': webqtlCaseData(3), 'BXD11': webqtlCaseData(4), 'BXD12': webqtlCaseData(3),
+ 'BXD13': webqtlCaseData(2), 'BXD18': webqtlCaseData(3), 'BXD19': webqtlCaseData(3),
+ 'BXD38': webqtlCaseData(3), 'BXD39': webqtlCaseData(3), 'BXD36': webqtlCaseData(2),
+ 'BXD34': webqtlCaseData(4), 'BXD35': webqtlCaseData(4), 'BXD32': webqtlCaseData(4),
+ 'BXD33': webqtlCaseData(3), 'BXD30': webqtlCaseData(1), 'BXD31': webqtlCaseData(4),
+ 'DBA/2J': webqtlCaseData(1), 'BXD8': webqtlCaseData(3), 'BXD9': webqtlCaseData(1),
+ 'BXD6': webqtlCaseData(3), 'BXD5': webqtlCaseData(3), 'BXD2': webqtlCaseData(4),
+ 'BXD1': webqtlCaseData(1), 'C57BL/6J': webqtlCaseData(4), 'B6D2F1': webqtlCaseData(4),
+ 'BXD42': webqtlCaseData(4), 'BXD40': webqtlCaseData(3)}
+
diff --git a/web/webqtl/base/webqtlTrait.py b/web/webqtl/base/webqtlTrait.py
new file mode 100644
index 00000000..f5051e45
--- /dev/null
+++ b/web/webqtl/base/webqtlTrait.py
@@ -0,0 +1,581 @@
+import string
+
+from htmlgen import HTMLgen2 as HT
+
+import webqtlConfig
+from webqtlCaseData import webqtlCaseData
+from webqtlDataset import webqtlDataset
+from dbFunction import webqtlDatabaseFunction
+from utility import webqtlUtil
+
+
+class webqtlTrait:
+ """
+ Trait class defines a trait in webqtl, can be either Microarray,
+ Published phenotype, genotype, or user input trait
+ """
+
+ def __init__(self, cursor = None, **kw):
+ self.cursor = cursor
+ self.db = None # database object
+ self.name = '' # Trait ID, ProbeSet ID, Published ID, etc.
+ self.cellid = ''
+ self.identification = 'un-named trait'
+ self.riset = ''
+ self.haveinfo = 0
+ self.sequence = '' # Blat sequence, available for ProbeSet
+ self.data = {}
+ for name, value in kw.items():
+ if self.__dict__.has_key(name):
+ setattr(self, name, value)
+ elif name == 'fullname':
+ name2 = value.split("::")
+ if len(name2) == 2:
+ self.db, self.name = name2
+ elif len(name2) == 3:
+ self.db, self.name, self.cellid = name2
+ else:
+ raise KeyError, `value` + ' parameter format error.'
+ else:
+ raise KeyError, `name`+' not a valid parameter for this class.'
+
+ if self.db and type(self.db) == type("1"):
+ assert self.cursor
+ self.db = webqtlDataset(self.db, self.cursor)
+
+ #if self.db == None, not from a database
+ if self.db:
+ if self.db.type == "Temp":
+ self.cursor.execute('''
+ SELECT
+ InbredSet.Name
+ FROM
+ InbredSet, Temp
+ WHERE
+ Temp.InbredSetId = InbredSet.Id AND
+ Temp.Name = "%s"
+ ''' % self.name)
+ self.riset = self.cursor.fetchone()[0]
+ else:
+ self.riset = self.db.getRISet()
+
+ #
+ # In ProbeSet, there are maybe several annotations match one sequence
+ # so we need use sequence(BlatSeq) as the identification, when we update
+ # one annotation, we update the others who match the sequence also.
+ #
+ # Hongqiang Li, 3/3/2008
+ #
+
+ #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield.
+ # The variable self.sequence should be changed to self.BlatSeq
+ # It also should be changed in other places where it are used.
+
+ if self.db:
+ if self.db.type == 'ProbeSet':
+ query = '''
+ SELECT
+ ProbeSet.BlatSeq
+ FROM
+ ProbeSet, ProbeSetFreeze, ProbeSetXRef
+ WHERE
+ ProbeSet.Id=ProbeSetXRef.ProbeSetId and
+ ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and
+ ProbeSet.Name = "%s" and
+ ProbeSetFreeze.Name = "%s"
+ ''' % (self.name, self.db.name)
+ self.cursor.execute(query)
+ self.sequence = self.cursor.fetchone()[0]
+
+
+ def getName(self):
+ str = ""
+ if self.db and self.name:
+ str = "%s::%s" % (self.db, self.name)
+ if self.cellid:
+ str += "::" + self.cellid
+ else:
+ str = self.description
+ return str
+
+ #
+ # when user enter a trait or GN generate a trait, user want show the name
+ # not the name that generated by GN randomly, the two follow function are
+ # used to give the real name and the database. displayName() will show the
+ # database also, getGivenName() just show the name.
+ # For other trait, displayName() as same as getName(), getGivenName() as
+ # same as self.name
+ #
+ # Hongqiang 11/29/07
+ #
+ def getGivenName(self):
+ str = self.name
+ if self.db and self.name:
+ if self.db.type=='Temp':
+ self.cursor.execute('SELECT description FROM Temp WHERE Name=%s',self.name)
+ desc = self.cursor.fetchone()[0]
+ if desc.__contains__('PCA'):
+ desc = desc[desc.rindex(':')+1:].strip()
+ else:
+ desc = desc[:desc.index('entered')].strip()
+ str = desc
+ return str
+
+ def displayName(self):
+ str = ""
+ if self.db and self.name:
+ if self.db.type=='Temp':
+ desc = self.description
+ if desc.__contains__('PCA'):
+ desc = desc[desc.rindex(':')+1:].strip()
+ else:
+ desc = desc[:desc.index('entered')].strip()
+ str = "%s::%s" % (self.db, desc)
+ else:
+ str = "%s::%s" % (self.db, self.name)
+ if self.cellid:
+ str += "::" + self.cellid
+ else:
+ str = self.description
+
+ return str
+
+
+ #def __str__(self):
+ # #return "%s %s" % (self.getName(), self.riset)
+ # return self.getName()
+ __str__ = getName
+ __repr__ = __str__
+
+ def exportData(self, strainlist, type="val"):
+ """
+ export data according to strainlist
+ mostly used in calculating correlation
+ """
+ result = []
+ for strain in strainlist:
+ if self.data.has_key(strain):
+ if type=='val':
+ result.append(self.data[strain].val)
+ elif type=='var':
+ result.append(self.data[strain].var)
+ elif type=='N':
+ result.append(self.data[strain].N)
+ else:
+ raise KeyError, `type`+' type is incorrect.'
+ else:
+ result.append(None)
+ return result
+
+ def exportInformative(self, incVar=0):
+ """
+ export informative strain
+ mostly used in qtl regression
+ """
+ strains = []
+ vals = []
+ vars = []
+ for strain, value in self.data.items():
+ if value.val != None:
+ if not incVar or value.var != None:
+ strains.append(strain)
+ vals.append(value.val)
+ vars.append(value.var)
+ return strains, vals, vars
+
+
+ #
+ # In ProbeSet, there are maybe several annotations match one sequence
+ # so we need use sequence(BlatSeq) as the identification, when we update
+ # one annotation, we update the others who match the sequence also.
+ #
+ # Hongqiang Li, 3/3/2008
+ #
+ def getSequence(self):
+ assert self.cursor
+ if self.db.type == 'ProbeSet':
+ query = '''
+ SELECT
+ ProbeSet.BlatSeq
+ FROM
+ ProbeSet, ProbeSetFreeze, ProbeSetXRef
+ WHERE
+ ProbeSet.Id=ProbeSetXRef.ProbeSetId and
+ ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and
+ ProbeSet.Name = %s
+ ProbeSetFreeze.Name = %s
+ ''' , (self.name, self.db.name)
+ self.cursor.execute(query)
+ results = self.fetchone()
+
+ return results[0]
+
+
+
+ def retrieveData(self, strainlist=[]):
+ assert self.db and self.cursor
+
+ if self.db.type == 'Temp':
+ query = '''
+ SELECT
+ Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id
+ FROM
+ TempData, Temp, Strain
+ WHERE
+ TempData.StrainId = Strain.Id AND
+ TempData.Id = Temp.DataId AND
+ Temp.name = '%s'
+ Order BY
+ Strain.Name
+ ''' % self.name
+ #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE
+ elif self.db.type == 'Publish':
+ query = '''
+ SELECT
+ Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id
+ FROM
+ (PublishData, Strain, PublishXRef, PublishFreeze)
+ left join PublishSE on
+ (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId)
+ left join NStrain on
+ (NStrain.DataId = PublishData.Id AND
+ NStrain.StrainId = PublishData.StrainId)
+ WHERE
+ PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND
+ PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND
+ PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id
+ Order BY
+ Strain.Name
+ ''' % (self.name, self.db.id)
+
+ #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE
+ elif self.cellid:
+ #Probe Data
+ query = '''
+ SELECT
+ Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id
+ FROM
+ (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef,
+ Strain, Probe, ProbeSet)
+ left join ProbeSE on
+ (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId)
+ WHERE
+ Probe.Name = '%s' AND ProbeSet.Name = '%s' AND
+ Probe.ProbeSetId = ProbeSet.Id AND
+ ProbeXRef.ProbeId = Probe.Id AND
+ ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND
+ ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND
+ ProbeSetFreeze.Name = '%s' AND
+ ProbeXRef.DataId = ProbeData.Id AND
+ ProbeData.StrainId = Strain.Id
+ Order BY
+ Strain.Name
+ ''' % (self.cellid, self.name, self.db.name)
+ #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE
+ elif self.db.type == 'ProbeSet':
+ #ProbeSet Data
+ query = '''
+ SELECT
+ Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id
+ FROM
+ (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef)
+ left join ProbeSetSE on
+ (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId)
+ WHERE
+ ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
+ ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND
+ ProbeSetFreeze.Name = '%s' AND
+ ProbeSetXRef.DataId = ProbeSetData.Id AND
+ ProbeSetData.StrainId = Strain.Id
+ Order BY
+ Strain.Name
+ ''' % (self.name, self.db.name)
+ #XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE
+ else:
+ #Geno Data
+ #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search.
+ query = '''
+ SELECT
+ Strain.Name, GenoData.value, GenoSE.error, GenoData.Id
+ FROM
+ (GenoData, GenoFreeze, Strain, Geno, GenoXRef)
+ left join GenoSE on
+ (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId)
+ WHERE
+ Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND
+ GenoXRef.GenoFreezeId = GenoFreeze.Id AND
+ GenoFreeze.Name = '%s' AND
+ GenoXRef.DataId = GenoData.Id AND
+ GenoData.StrainId = Strain.Id
+ Order BY
+ Strain.Name
+ ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.db.riset), self.name, self.db.name)
+
+
+ self.cursor.execute(query)
+ results = self.cursor.fetchall()
+ self.data.clear()
+ if results:
+ self.mysqlid = results[0][-1]
+ if strainlist:
+ for item in results:
+ if item[0] in strainlist:
+ val = item[1]
+ if val != None:
+ var = item[2]
+ ndata = None
+ if self.db.type in ('Publish', 'Temp'):
+ ndata = item[3]
+ self.data[item[0]] = webqtlCaseData(val, var, ndata)
+ #end for
+ else:
+ for item in results:
+ val = item[1]
+ if val != None:
+ var = item[2]
+ ndata = None
+ if self.db.type in ('Publish', 'Temp'):
+ ndata = item[3]
+ self.data[item[0]] = webqtlCaseData(val, var, ndata)
+ #end for
+ #end if
+ else:
+ pass
+
+ def keys(self):
+ return self.__dict__.keys()
+
+ def has_key(self, key):
+ return self.__dict__.has_key(key)
+
+ def items(self):
+ return self.__dict__.items()
+
+ def retrieveInfo(self, QTL = None):
+ assert self.db and self.cursor
+ if self.db.type == 'Publish':
+ #self.db.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\
+ # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\
+ # 'Units', 'comments']
+ query = '''
+ SELECT
+ PublishXRef.Id, Publication.PubMed_ID,
+ Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description,
+ Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation,
+ Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users,
+ Publication.Authors, Publication.Title, Publication.Abstract,
+ Publication.Journal, Publication.Volume, Publication.Pages,
+ Publication.Month, Publication.Year, PublishXRef.Sequence,
+ Phenotype.Units, PublishXRef.comments
+ FROM
+ PublishXRef, Publication, Phenotype, PublishFreeze
+ WHERE
+ PublishXRef.Id = %s AND
+ Phenotype.Id = PublishXRef.PhenotypeId AND
+ Publication.Id = PublishXRef.PublicationId AND
+ PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND
+ PublishFreeze.Id =%s
+ ''' % (self.name, self.db.id)
+ #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name
+ #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms.
+ elif self.db.type == 'ProbeSet':
+ disfieldString = string.join(self.db.disfield,',ProbeSet.')
+ disfieldString = 'ProbeSet.' + disfieldString
+ query = """
+ SELECT %s
+ FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef
+ WHERE
+ ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND
+ ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
+ ProbeSetFreeze.Name = '%s' AND
+ ProbeSet.Name = '%s'
+ """ % (disfieldString, self.db.name, self.name)
+ #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name
+ # to avoid the problem of same marker name from different species.
+ elif self.db.type == 'Geno':
+ disfieldString = string.join(self.db.disfield,',Geno.')
+ disfieldString = 'Geno.' + disfieldString
+ query = """
+ SELECT %s
+ FROM Geno, GenoFreeze, GenoXRef
+ WHERE
+ GenoXRef.GenoFreezeId = GenoFreeze.Id AND
+ GenoXRef.GenoId = Geno.Id AND
+ GenoFreeze.Name = '%s' AND
+ Geno.Name = '%s'
+ """ % (disfieldString, self.db.name, self.name)
+ else: #Temp type
+ query = 'SELECT %s FROM %s WHERE Name = "%s"' % \
+ (string.join(self.db.disfield,','), self.db.type, self.name)
+
+
+ self.cursor.execute(query)
+ traitInfo = self.cursor.fetchone()
+ if traitInfo:
+ self.haveinfo = 1
+
+ #XZ: assign SQL query result to trait attributes.
+ for i, field in enumerate(self.db.disfield):
+ setattr(self, field, traitInfo[i])
+
+ if self.db.type == 'Publish':
+ self.confidential = 0
+ if self.pre_publication_description and not self.pubmed_id:
+ self.confidential = 1
+
+ self.homologeneid = None
+ if self.db.type == 'ProbeSet' and self.riset and self.geneid:
+ #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number.
+ #XZ: So I have to test if geneid is number before execute the query.
+ #XZ: The geneid values in database should be cleaned up.
+ try:
+ junk = float(self.geneid)
+ geneidIsNumber = 1
+ except:
+ geneidIsNumber = 0
+
+ if geneidIsNumber:
+ query = """
+ SELECT
+ HomologeneId
+ FROM
+ Homologene, Species, InbredSet
+ WHERE
+ Homologene.GeneId =%s AND
+ InbredSet.Name = '%s' AND
+ InbredSet.SpeciesId = Species.Id AND
+ Species.TaxonomyId = Homologene.TaxonomyId
+ """ % (self.geneid, self.riset)
+ self.cursor.execute(query)
+ result = self.cursor.fetchone()
+ else:
+ result = None
+
+ if result:
+ self.homologeneid = result[0]
+
+ if QTL:
+ if self.db.type == 'ProbeSet' and not self.cellid:
+ query = '''
+ SELECT
+ ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean
+ FROM
+ ProbeSetXRef, ProbeSet
+ WHERE
+ ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
+ ProbeSet.Name = "%s" AND
+ ProbeSetXRef.ProbeSetFreezeId =%s
+ ''' % (self.name, self.db.id)
+ self.cursor.execute(query)
+ traitQTL = self.cursor.fetchone()
+ if traitQTL:
+ self.locus, self.lrs, self.pvalue, self.mean = traitQTL
+ else:
+ self.locus = self.lrs = self.pvalue = self.mean = ""
+ if self.db.type == 'Publish':
+ query = '''
+ SELECT
+ PublishXRef.Locus, PublishXRef.LRS
+ FROM
+ PublishXRef, PublishFreeze
+ WHERE
+ PublishXRef.Id = %s AND
+ PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND
+ PublishFreeze.Id =%s
+ ''' % (self.name, self.db.id)
+ self.cursor.execute(query)
+ traitQTL = self.cursor.fetchone()
+ if traitQTL:
+ self.locus, self.lrs = traitQTL
+ else:
+ self.locus = self.lrs = ""
+ else:
+ raise KeyError, `self.name`+' information is not found in the database.'
+
+ def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""):
+ if not self.haveinfo:
+ self.retrieveInfo()
+
+ if self.db.type == 'Publish':
+ PubMedLink = ""
+ if self.pubmed_id:
+ PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id,
+ target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id)
+ else:
+ PubMedLink = HT.Span("Unpublished : ", Class="fs15")
+
+ if formName:
+ setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" %
+ (formName, self.db.name, self.name), Class = "fs14")
+ else:
+ setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" %
+ (self.db.name,self.name), Class = "fs14")
+
+ if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users):
+ setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description))
+ else:
+ setDescription2.append('RecordID/%s - %s' % (self.name, self.post_publication_description))
+
+ #XZ 03/26/2011: Xiaodong comment out the following two lins as Rob asked. Need to check with Rob why in PublishXRef table, there are few row whose Sequence > 1.
+ #if self.sequence > 1:
+ # setDescription2.append(' btach %d' % self.sequence)
+ if self.authors:
+ a1 = string.split(self.authors,',')[0]
+ while a1[0] == '"' or a1[0] == "'" :
+ a1 = a1[1:]
+ setDescription2.append(' by ')
+ setDescription2.append(HT.Italic('%s, and colleagues' % a1))
+ setDescription = HT.Span(PubMedLink, setDescription2)
+
+ elif self.db.type == 'Temp':
+ setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\
+ ('%s','%s','')" % (self.db.name,self.name), Class = "fs14")
+ setDescription = HT.Span(setDescription)
+
+ elif self.db.type == 'Geno': # Genome DB only available for single search
+ if formName:
+ setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\
+ '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \
+ (formName, self.db.name, self.name), Class = "fs14")
+ else:
+ setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\
+ '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \
+ (self.db.name,self.name), Class = "fs14")
+
+ setDescription = HT.Span(setDescription)
+
+ else:
+ if self.cellid:
+ if formName:
+ setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\
+ "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.db.name,self.name,self.cellid), \
+ Class = "fs14")
+ else:
+ setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\
+ "javascript:showDatabase2('%s','%s','%s')" % (self.db.name,self.name,self.cellid), \
+ Class = "fs14")
+ else:
+ if formName:
+ setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\
+ "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.db.name,self.name), \
+ Class = "fs14")
+ else:
+ setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\
+ "javascript:showDatabase2('%s','%s','')" % (self.db.name,self.name), \
+ Class = "fs14")
+ if self.symbol and self.chr and self.mb:
+ setDescription.append(' [')
+ setDescription.append(HT.Italic('%s' % self.symbol,Class="cdg fwb"))
+ setDescription.append(' on Chr %s @ %s Mb]' % (self.chr,self.mb))
+ if self.description:
+ setDescription.append(': %s' % self.description)
+ if self.probe_target_description:
+ setDescription.append('; %s' % self.probe_target_description)
+ setDescription = HT.Span(setDescription)
+
+ if self.db.type != 'Temp' and dispFromDatabase:
+ setDescription.append( ' --- FROM : ')
+ setDescription.append(self.db.genHTML(Class='cori'))
+ return setDescription
+
+
diff --git a/web/webqtl/basicStatistics/BasicStatisticsFunctions.py b/web/webqtl/basicStatistics/BasicStatisticsFunctions.py
new file mode 100755
index 00000000..a22b50a2
--- /dev/null
+++ b/web/webqtl/basicStatistics/BasicStatisticsFunctions.py
@@ -0,0 +1,174 @@
+#import string
+from math import *
+import piddle as pid
+#import os
+
+import reaper
+from htmlgen import HTMLgen2 as HT
+
+from utility import Plot
+from utility import webqtlUtil
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+
+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 plotNormalProbability(vals=None, RISet='', title=None, showstrains=0, specialStrains=[None], size=(750,500)):
+
+ dataXZ = vals[:]
+ dataXZ.sort(webqtlUtil.cmpOrder)
+ dataLabel = []
+ dataX = map(lambda X: X[1], dataXZ)
+
+ showLabel = showstrains
+ if len(dataXZ) > 50:
+ showLabel = 0
+ for item in dataXZ:
+ strainName = webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=item[0])
+ dataLabel.append(strainName)
+
+ dataY=Plot.U(len(dataX))
+ dataZ=map(Plot.inverseCumul,dataY)
+ c = pid.PILCanvas(size=(750,500))
+ Plot.plotXY(c, dataZ, dataX, dataLabel = dataLabel, XLabel='Expected Z score', connectdot=0, YLabel='Trait value', title=title, specialCases=specialStrains, showLabel = showLabel)
+
+ filename= webqtlUtil.genRandStr("nP_")
+ c.save(webqtlConfig.IMGDIR+filename, format='gif')
+
+ img=HT.Image('/image/'+filename+'.gif',border=0)
+
+ return img
+
+def plotBoxPlot(vals):
+
+ valsOnly = []
+ dataXZ = vals[:]
+ for i in range(len(dataXZ)):
+ valsOnly.append(dataXZ[i][1])
+
+ plotHeight = 320
+ plotWidth = 220
+ xLeftOffset = 60
+ xRightOffset = 40
+ yTopOffset = 40
+ yBottomOffset = 60
+
+ canvasHeight = plotHeight + yTopOffset + yBottomOffset
+ canvasWidth = plotWidth + xLeftOffset + xRightOffset
+ canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight))
+ XXX = [('', valsOnly[:])]
+
+ 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)
+
+ plotLink = HT.Span("More about ", HT.Href(text="Box Plots", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs13"))
+
+ return img, plotLink
+
+def plotBarGraph(identification='', RISet='', vals=None, type="name"):
+
+ this_identification = "unnamed trait"
+ if identification:
+ this_identification = identification
+
+ if type=="rank":
+ dataXZ = vals[:]
+ dataXZ.sort(webqtlUtil.cmpOrder)
+ title='%s' % this_identification
+ else:
+ dataXZ = vals[:]
+ title='%s' % this_identification
+
+ tvals = []
+ tnames = []
+ tvars = []
+ for i in range(len(dataXZ)):
+ tvals.append(dataXZ[i][1])
+ tnames.append(webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=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=title, sLabel = sLabel, barSpace = sw)
+
+ filename= webqtlUtil.genRandStr("Bar_")
+ c.save(webqtlConfig.IMGDIR+filename, format='gif')
+ img=HT.Image('/image/'+filename+'.gif',border=0)
+
+ return img
diff --git a/web/webqtl/basicStatistics/BasicStatisticsPage_alpha.py b/web/webqtl/basicStatistics/BasicStatisticsPage_alpha.py
new file mode 100755
index 00000000..4ba9d54a
--- /dev/null
+++ b/web/webqtl/basicStatistics/BasicStatisticsPage_alpha.py
@@ -0,0 +1,348 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import string
+from math import *
+import piddle as pid
+import os
+
+from htmlgen import HTMLgen2 as HT
+import reaper
+
+from utility import Plot
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+
+
+
+class BasicStatisticsPage_alpha(templatePage):
+
+ plotMinInformative = 4
+
+ 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
+
+ def traitInfo(self, fd, specialStrains = None):
+ species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet)
+ heading2 = HT.Paragraph(HT.Strong('Population: '), "%s %s" % (species.title(), fd.RISet) , HT.BR())
+ if self.Trait:
+ trait_url = HT.Href(text=self.Trait.name, url = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + \
+ "?FormID=showDatabase&incparentsf1=1&database=%s&ProbeSetID=%s" % (self.Trait.db.name, self.Trait.name), \
+ target='_blank', Class="fs13 fwn")
+ heading2.append(HT.Strong("Database: "),
+ HT.Href(text=self.Trait.db.fullname, url = webqtlConfig.INFOPAGEHREF % self.Trait.db.name ,
+ target='_blank',Class="fs13 fwn"),HT.BR())
+ if self.Trait.db.type == 'ProbeSet':
+ heading2.append(HT.Strong('Trait ID: '), trait_url, HT.BR(),
+ HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.symbol,id="green"),HT.BR())
+ if self.Trait.chr and self.Trait.mb:
+ heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb))
+ elif self.Trait.db.type == 'Geno':
+ heading2.append(HT.Strong('Locus : '), trait_url, HT.BR())
+ #heading2.append(HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.Symbol,id="green"),HT.BR())
+ if self.Trait.chr and self.Trait.mb:
+ heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb))
+ elif self.Trait.db.type == 'Publish':
+ heading2.append(HT.Strong('Record ID: '), trait_url, HT.BR())
+ heading2.append(HT.Strong('Phenotype: '), self.Trait.phenotype, HT.BR())
+ heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR())
+ elif self.Trait.db.type == 'Temp':
+ heading2.append(HT.Strong('Description: '), self.Trait.description, HT.BR())
+ #heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR())
+ else:
+ pass
+ else:
+ heading2.append(HT.Strong("Trait Name: "), fd.identification)
+
+ if specialStrains:
+ mdpform = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='MDP_Form',submit=HT.Input(type='hidden'))
+ mdphddn = {'FormID':'dataEditing', 'submitID':'basicStatistics','RISet':fd.RISet, "allstrainlist":string.join(fd.allstrainlist, " "), "ptype":self.plotType, 'identification':fd.identification, "incparentsf1":1}
+ if self.fullname: mdphddn['fullname'] = self.fullname
+ webqtlUtil.exportData(mdphddn, fd.allTraitData)
+ for key in mdphddn.keys():
+ mdpform.append(HT.Input(name=key, value=mdphddn[key], type='hidden'))
+ btn0 = HT.Input(type='button' ,name='',value='All Cases',onClick="this.form.ptype.value=0;submit();", Class="button")
+ btn1 = HT.Input(type='button' ,name='',value='%s Only' % fd.RISet,onClick="this.form.ptype.value=1;submit();", Class="button")
+ btn2 = HT.Input(type='button' ,name='',value='MDP Only', onClick="this.form.ptype.value=2;submit();", Class="button")
+ mdpform.append(btn0)
+ mdpform.append(btn1)
+ mdpform.append(btn2)
+ heading2.append(HT.P(), mdpform)
+
+ return HT.Span(heading2)
+
+ def calSD(self,var):
+ try:
+ return sqrt(abs(var))
+ except:
+ return None
+
+
+ def cmpValue(self,A,B):
+ try:
+ if A[1] < B[1]:
+ return -1
+ elif A[1] == B[1]:
+ return 0
+ else:
+ return 1
+ except:
+ return 0
+
+
+
+
diff --git a/web/webqtl/basicStatistics/__init__.py b/web/webqtl/basicStatistics/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py b/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py
new file mode 100755
index 00000000..156dafe7
--- /dev/null
+++ b/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py
@@ -0,0 +1,150 @@
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from dbFunction import webqtlDatabaseFunction
+import BasicStatisticsFunctions
+
+#Window generated from the Trait Data and Analysis page (DataEditingPage.py) with updated stats figures; takes the page's values that can bed edited by the user
+class updatedBasicStatisticsPage(templatePage):
+
+ plotMinInformative = 4
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not fd.genotype:
+ fd.readGenotype()
+ this_strainlist = fd.strainlist
+
+ if fd.allstrainlist:
+ this_strainlist = fd.allstrainlist
+
+ fd.readData(this_strainlist)
+
+ specialStrains = [] #This appears to be the "other/non-RISet strainlist" without parents/f1 strains; not sure what to name it
+ setStrains = []
+ for item in this_strainlist:
+ if item not in fd.strainlist and item.find('F1') < 0:
+ specialStrains.append(item)
+ else:
+ continue
+
+ specialStrains.sort()
+ if specialStrains:
+ specialStrains = fd.f1list+fd.parlist+specialStrains
+
+ self.dict['title'] = 'Basic Statistics'
+ TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa")
+
+ stats_row = HT.TR()
+ stats_cell = HT.TD()
+ stats_script = HT.Script(language="Javascript")
+
+ #Get strain names, values, and variances
+ strain_names = fd.formdata.getvalue('strainNames').split(',')
+ strain_vals = fd.formdata.getvalue('strainVals').split(',')
+ strain_vars = fd.formdata.getvalue('strainVars').split(',')
+
+ vals = []
+ if (len(strain_names) > 0):
+ if (len(strain_names) > 3):
+ #Need to create "vals" object
+ for i in range(len(strain_names)):
+ try:
+ this_strain_val = float(strain_vals[i])
+ except:
+ continue
+ try:
+ this_strain_var = float(strain_vars[i])
+ except:
+ this_strain_var = None
+
+ thisValFull = [strain_names[i], this_strain_val, this_strain_var]
+ vals.append(thisValFull)
+
+ stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-5", Class="stats_tab"),
+ HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"),
+ HT.Href(text="Box Plot", url="#statstabs-2", Class="stats_tab")]
+ stats_tabs = HT.List(stats_tab_list)
+
+ stats_container = HT.Div(id="stats_tabs", Class="ui-tabs")
+ stats_container.append(stats_tabs)
+
+ stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" #Javascript enabling tabs
+
+ table_div = HT.Div(id="statstabs-1")
+ table_container = HT.Paragraph()
+
+ statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%")
+ this_trait_type = fd.formdata.getvalue('trait_type', None)
+ this_cellid = fd.formdata.getvalue('cellid', None)
+ statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait_type, cellid=this_cellid)
+ statsTable.append(HT.TR(HT.TD(statsTableCell)))
+
+ table_container.append(statsTable)
+ table_div.append(table_container)
+ stats_container.append(table_div)
+
+ boxplot_div = HT.Div(id="statstabs-2")
+ boxplot_container = HT.Paragraph()
+ boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%")
+ boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals)
+ boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left")))
+ boxplot_container.append(boxplot)
+ boxplot_div.append(boxplot_container)
+ stats_container.append(boxplot_div)
+
+ barName_div = HT.Div(id="statstabs-3")
+ barName_container = HT.Paragraph()
+ barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%")
+ barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name")
+ barName.append(HT.TR(HT.TD(barName_img)))
+ barName_container.append(barName)
+ barName_div.append(barName_container)
+ stats_container.append(barName_div)
+
+ barRank_div = HT.Div(id="statstabs-4")
+ barRank_container = HT.Paragraph()
+ barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%")
+ barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank")
+ barRank.append(HT.TR(HT.TD(barRank_img)))
+ barRank_container.append(barRank)
+ barRank_div.append(barRank_container)
+ stats_container.append(barRank_div)
+
+ normalplot_div = HT.Div(id="statstabs-5")
+ normalplot_container = HT.Paragraph()
+ normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%")
+ plotTitle = fd.formdata.getvalue("normalPlotTitle","")
+ normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains)
+ normalplot.append(HT.TR(HT.TD(normalplot_img)))
+ normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \
+ normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(),
+ "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot",
+ target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary"))))
+ normalplot_container.append(normalplot)
+ normalplot_div.append(normalplot_container)
+ stats_container.append(normalplot_div)
+
+ stats_cell.append(stats_container)
+ stats_script.append(stats_script_text)
+
+ submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%")
+ stats_row.append(stats_cell)
+
+ submitTable.append(stats_row)
+ submitTable.append(stats_script)
+
+ TD_LR.append(submitTable)
+ 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
\ No newline at end of file
diff --git a/web/webqtl/cmdLine/__init__.py b/web/webqtl/cmdLine/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/cmdLine/cmdCompCorrPage.py b/web/webqtl/cmdLine/cmdCompCorrPage.py
new file mode 100755
index 00000000..f53e1bce
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdCompCorrPage.py
@@ -0,0 +1,49 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+
+class cmdCompCorrPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Correlation Comparison", "Correlation Comparison in progress")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py correlationComparison %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdCorrelationPage.py b/web/webqtl/cmdLine/cmdCorrelationPage.py
new file mode 100755
index 00000000..4c76dc0b
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdCorrelationPage.py
@@ -0,0 +1,53 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+#########################################
+# Correlation Page
+#########################################
+class cmdCorrelationPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Correlation", "Correlation Computation in Progress")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py correlation %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
+
diff --git a/web/webqtl/cmdLine/cmdDirectPlotPage.py b/web/webqtl/cmdLine/cmdDirectPlotPage.py
new file mode 100755
index 00000000..21e936dc
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdDirectPlotPage.py
@@ -0,0 +1,49 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+
+class cmdDirectPlotPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Pair Scan", "Pair Scan Computation in Progress")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py directplot %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdHeatmapPage.py b/web/webqtl/cmdLine/cmdHeatmapPage.py
new file mode 100755
index 00000000..e96f3449
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdHeatmapPage.py
@@ -0,0 +1,52 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+#########################################
+# QTL Heatmap Page
+#########################################
+
+class cmdHeatmapPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("QTL Heatmap", "Computing QTL Heatmap")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py heatmap %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdIntervalMappingPage.py b/web/webqtl/cmdLine/cmdIntervalMappingPage.py
new file mode 100755
index 00000000..8e0a3d92
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdIntervalMappingPage.py
@@ -0,0 +1,75 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+#########################################
+# Interval Mapping Page
+#########################################
+
+class cmdIntervalMappingPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ wtext = "Mapping "
+ try:
+ selectedChr = int(fd.formdata.getvalue('chromosomes')) + 1
+ if selectedChr < 1:
+ raise "ValueError"
+ if selectedChr == 21 or (selectedChr == 20 and fd.RISet != 'HXBBXH'):
+ selectedChr = 'X'
+ wtext += 'chromosome %s ' % selectedChr
+ except:
+ wtext += 'whole genome '
+
+ perm = 0
+ if fd.formdata.getvalue('permCheck'):
+ perm = 1
+ wtext += 'with %d permutation tests ' % fd.nperm
+
+ boot = 0
+ if fd.formdata.getvalue('bootCheck'):
+ boot = 1
+ if perm:
+ wtext += 'and %d bootstrap tests ' % fd.nboot
+ else:
+ wtext += 'with %d bootstrap tests ' % fd.nboot
+
+ if boot == 0 and perm == 0:
+ wtext += "without permutation or bootstrap tests"
+
+ filename = self.session("Interval Mapping", wtext)
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+ os.system("%s %swebqtlCmdLine.py interval %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+ self.redirection = url
+
diff --git a/web/webqtl/cmdLine/cmdMarkerRegressionPage.py b/web/webqtl/cmdLine/cmdMarkerRegressionPage.py
new file mode 100755
index 00000000..fb974e33
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdMarkerRegressionPage.py
@@ -0,0 +1,47 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by NL 2011/03/15
+#
+# Last updated by NL 2011/03/15
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+#########################################
+# Marker RegressionPage Page
+#########################################
+
+class cmdMarkerRegressionPage(templatePage):
+
+ def __init__(self,fd):
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Genome Association Result", "Computing Genome Association Results")
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+ os.system("%s %swebqtlCmdLine.py markerRegression %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdNetworkGraphPage.py b/web/webqtl/cmdLine/cmdNetworkGraphPage.py
new file mode 100755
index 00000000..a16fcbaf
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdNetworkGraphPage.py
@@ -0,0 +1,49 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+
+class cmdNetworkGraphPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Network Graph", "Computing Network Graph")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename + '.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py networkGraph %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdPartialCorrelationPage.py b/web/webqtl/cmdLine/cmdPartialCorrelationPage.py
new file mode 100755
index 00000000..fb5324c6
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdPartialCorrelationPage.py
@@ -0,0 +1,50 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+########################################
+# Partial Correlation Page
+########################################
+class cmdPartialCorrelationPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Partial Correlation", "Partial Correlation in Progress")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py partialCorrelation %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdQTLminerPage.py b/web/webqtl/cmdLine/cmdQTLminerPage.py
new file mode 100755
index 00000000..2197d3ce
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdQTLminerPage.py
@@ -0,0 +1,47 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by NL 2011/03/15
+#
+# Last updated by NL 2011/03/15
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+#########################################
+# QTLminer Page
+#########################################
+
+class cmdQTLminerPage(templatePage):
+
+ def __init__(self,fd):
+ templatePage.__init__(self, fd)
+
+ filename = self.session("QTLminer Result", "Computing QTLminer Results")
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+ os.system("%s %swebqtlCmdLine.py QTLminer %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdShowAllPage.py b/web/webqtl/cmdLine/cmdShowAllPage.py
new file mode 100755
index 00000000..37e159e9
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdShowAllPage.py
@@ -0,0 +1,50 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+
+class cmdShowAllPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Generate Report", "Generating Report. Please be Patient")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py genreport %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
+
diff --git a/web/webqtl/cmdLine/cmdShowAllPage2.py b/web/webqtl/cmdLine/cmdShowAllPage2.py
new file mode 100755
index 00000000..a1ac172f
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdShowAllPage2.py
@@ -0,0 +1,55 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+
+#########################################
+# Generate Report Page
+#########################################
+
+class cmdShowAllPage2(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Generate Report v2", "Generating Report v2. Please be Patient")
+
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+
+ os.system("%s %swebqtlCmdLine.py genreport2 %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+
+ self.redirection = url
+
+
diff --git a/web/webqtl/cmdLine/cmdSnpBrowserResultPage.py b/web/webqtl/cmdLine/cmdSnpBrowserResultPage.py
new file mode 100755
index 00000000..54cb1181
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdSnpBrowserResultPage.py
@@ -0,0 +1,47 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by NL 2011/03/15
+#
+# Last updated by NL 2011/03/15
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+#########################################
+# SnpBrowser Page
+#########################################
+
+class cmdSnpBrowserResultPage(templatePage):
+
+ def __init__(self,fd):
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Variant Browser Result", "Computing Variant Browser Results")
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+ os.system("%s %swebqtlCmdLine.py snpbrowser %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/cmdTissueCorrelationResultPage.py b/web/webqtl/cmdLine/cmdTissueCorrelationResultPage.py
new file mode 100755
index 00000000..1f28953c
--- /dev/null
+++ b/web/webqtl/cmdLine/cmdTissueCorrelationResultPage.py
@@ -0,0 +1,47 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by NL 2011/03/15
+#
+# Last updated by NL 2011/03/15
+
+import os
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+#########################################
+# SnpBrowser Page
+#########################################
+
+class cmdTissueCorrelationResultPage(templatePage):
+
+ def __init__(self,fd):
+ templatePage.__init__(self, fd)
+
+ filename = self.session("Tissue Correlation Result Page", "Computing Tissue Correlation Result")
+ webqtlUtil.dump_session(fd, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
+ url = webqtlConfig.REFRESHDIR % (webqtlConfig.CGIDIR, self.filename)
+ os.system("%s %swebqtlCmdLine.py tissueCorrelation %s >/dev/null 2>&1 &" % (webqtlConfig.PythonPath, webqtlConfig.CMDLINEDIR, filename))
+ self.redirection = url
diff --git a/web/webqtl/cmdLine/procPage.py b/web/webqtl/cmdLine/procPage.py
new file mode 100755
index 00000000..03ce242c
--- /dev/null
+++ b/web/webqtl/cmdLine/procPage.py
@@ -0,0 +1,46 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#--Only imported by WebQTL.py -KA
+
+#Xiaodong changed the dependancy structure
+
+import os
+
+from base import webqtlConfig
+
+
+class procPage:
+ def __init__(self, myID, req):
+ try:
+ fp = open(os.path.join(webqtlConfig.TMPDIR, myID + '.html'), 'rb')
+ except:
+ fp = open(os.path.join(webqtlConfig.ChangableHtmlPath, 'missing.html'), 'rb')
+
+ content = fp.read()
+ fp.close()
+ req.write(content)
+
diff --git a/web/webqtl/cmdLine/webqtlCmdLine.py b/web/webqtl/cmdLine/webqtlCmdLine.py
new file mode 100755
index 00000000..ebc10e1c
--- /dev/null
+++ b/web/webqtl/cmdLine/webqtlCmdLine.py
@@ -0,0 +1,176 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+
+
+########################################################
+#XZ, Aug 10, 2010
+#This part is the temporary solution to make python be able to find other subpackages.
+#We can't set global environment because there are many branches on the development machine.
+
+import sys, os
+
+current_file_name = __file__
+pathname = os.path.dirname( current_file_name )
+abs_path = os.path.abspath(pathname)
+sys.path.insert(0, abs_path + '/..')
+
+########################################################
+
+
+
+import traceback
+import string
+import cPickle
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+
+
+if __name__ == "__main__":
+ try:
+ if len(sys.argv) > 2:
+ getID = string.lower(sys.argv[1])
+ else:
+ raise ValueError
+
+ cmdtype = sys.argv[1]
+ sessionfile = sys.argv[2]
+
+ fd = None
+
+ fp = open(os.path.join(webqtlConfig.TMPDIR, sessionfile + '.session'), 'rb')
+ fd = cPickle.load(fp)
+ fp.close()
+
+ if cmdtype == "heatmap":
+ from heatmap import heatmapPage
+ reload(heatmapPage)
+ page = heatmapPage.heatmapPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "directplot":
+ from pairScan import DirectPlotPage
+ reload(DirectPlotPage)
+ page = DirectPlotPage.DirectPlotPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "networkGraph":
+ from networkGraph import networkGraphPage
+ reload(networkGraphPage)
+ page = networkGraphPage.networkGraphPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "interval":
+ from intervalMapping import IntervalMappingPage
+ reload(IntervalMappingPage)
+ page = IntervalMappingPage.IntervalMappingPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "correlation":
+ from correlation import CorrelationPage
+ reload (CorrelationPage)
+ page = CorrelationPage.CorrelationPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "partialCorrelation":
+ from correlation import PartialCorrDBPage
+ reload(PartialCorrDBPage)
+ page = PartialCorrDBPage.PartialCorrDBPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "correlationComparison":
+ from compareCorrelates import multitrait
+ reload(multitrait)
+ page = multitrait.compCorrPage(fd)
+ page.writeFile(sessionfile+'.html')
+ elif cmdtype == "genreport": # Generate Report Page
+ spacer = '
+
+
+ """
+
+ return layerString
+
+ def getCollectionTableHeader(self):
+
+ tblobj_header = []
+
+ className = "fs13 fwb ffl b1 cw cbrb"
+
+ tblobj_header = [[THCell(HT.TD(' ', Class=className, nowrap="on"), sort=0),
+ THCell(HT.TD('Dataset', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="dataset", idx=1),
+ THCell(HT.TD('Trait', HT.BR(), 'ID', HT.BR(), valign="top", Class=className, nowrap="on"), text="name", idx=2),
+ THCell(HT.TD('Symbol', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="symbol", idx=3),
+ THCell(HT.TD('Description', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="desc", idx=4),
+ THCell(HT.TD('Location', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="location", idx=5),
+ THCell(HT.TD('Mean', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="mean", idx=6),
+ THCell(HT.TD('N', HT.BR(), 'Cases', HT.BR(), valign="top", Class=className, nowrap="on"), text="samples", idx=7),
+ THCell(HT.TD('Max LRS', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="lrs", idx=8),
+ THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb', HT.BR(), valign="top", Class=className, nowrap="on"), text="lrs_location", idx=9)]]
+
+ return tblobj_header
+
+ 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)))
+
+ #XZ: Dataset column
+ tr.append(TDCell(HT.TD(thisTrait.db.name, Class="fs12 fwn b1 c222"), thisTrait.db.name, thisTrait.db.name.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()))
+
+ 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,End,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
+ 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 ProbeSetFreezeId=%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,End,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 and its location
+ LRS_score_repr = '--'
+ LRS_score_value = 0
+ 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_score_repr = '%3.1f' % thisTrait.lrs
+ LRS_score_value = thisTrait.lrs
+ LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) )
+ LRS_flag = 0
+
+ tr.append(TDCell(HT.TD(LRS_score_repr, Class=className, align='right', nowrap="on"), LRS_score_repr, LRS_score_value))
+ 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_score_repr, Class=className), LRS_score_repr, LRS_score_value))
+ 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))
+
+ tblobj_body.append(tr)
+
+ return tblobj_body
+
+ def getSortByValue(self):
+
+ sortby = ("pv", "up")
+
+ return sortby
+
+ def nullRecord(self,x):
+ if x or x == 0:
+ return x
+ else:
+ return ""
+
diff --git a/web/webqtl/collection/AddUserInputToSelectionPage.py b/web/webqtl/collection/AddUserInputToSelectionPage.py
new file mode 100755
index 00000000..2c69a047
--- /dev/null
+++ b/web/webqtl/collection/AddUserInputToSelectionPage.py
@@ -0,0 +1,97 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#AddUserInputToSelectionPage.py
+
+import time
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from AddToSelectionPage import AddToSelectionPage
+
+#########################################
+# Add UserInput to Selection Page
+#########################################
+class AddUserInputToSelectionPage(AddToSelectionPage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if not fd.genotype:
+ fd.readData(incf1 = 1)
+
+ self.strainlist = []
+ self.vals = []
+ for i, strain in enumerate(fd.f1list + fd.strainlist):
+ if fd.allTraitData.has_key(strain) and fd.allTraitData[strain].val != None:
+ self.strainlist.append(strain)
+ self.vals.append([fd.allTraitData[strain].val, fd.allTraitData[strain].var])
+
+ if len(self.strainlist) > webqtlConfig.KMININFORMATIVE:
+ pass
+ else:
+ templatePage.__init__(self, fd)
+ heading = 'Add to Collection'
+ detail = ['The number of informative strains in your trait is less than %d, this trait can not be added to the selection' % webqtlConfig.KMININFORMATIVE]
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.cursor.execute('delete Temp, TempData from Temp, TempData where Temp.DataId = TempData.Id and UNIX_TIMESTAMP()-UNIX_TIMESTAMP(CreateTime)>%d;' % webqtlConfig.MAXLIFE)
+ ct0 = time.localtime(time.time())
+ ct = time.strftime("%B/%d %H:%M:%S",ct0)
+ if not fd.identification:
+ fd.identification = "Unnamed Trait"
+ user_ip = fd.remote_ip
+ newDescription = '%s entered at %s from IP %s' % (fd.identification,ct,user_ip)
+ newProbeSetID = webqtlUtil.genRandStr("USER_Tmp_")
+ self.cursor.execute('SelecT max(id) from TempData')
+ try:
+ DataId = self.cursor.fetchall()[0][0] + 1
+ except:
+ DataId = 1
+ self.cursor.execute('SelecT Id from InbredSet where Name = "%s"' % fd.RISet)
+ InbredSetId = self.cursor.fetchall()[0][0]
+
+ self.cursor.execute('insert into Temp(Name,description, createtime,DataId,InbredSetId,IP) values(%s,%s,Now(),%s,%s,%s)' ,(newProbeSetID, newDescription, DataId,InbredSetId,user_ip))
+
+ k = 0
+ for Strain in self.strainlist:
+ self.cursor.execute('SelecT Strain.Id from Strain,StrainXRef where Strain.Name = "%s" and Strain.Id = StrainXRef.StrainId and StrainXRef.InbredSetId=%d' % (Strain, InbredSetId))
+ StrainId = self.cursor.fetchall()[0][0]
+ self.cursor.execute('insert into TempData(Id, StrainId, value, SE) values(%s,%s,%s,%s)' , (DataId, StrainId, self.vals[k][0], self.vals[k][1]))
+ k += 1
+
+ self.searchResult = ['Temp::%s' % newProbeSetID]
+
+ if self.genSelection(fd=fd):
+ self.writeHTML(fd)
+
+
diff --git a/web/webqtl/collection/BatchSubmitSelectionPage.py b/web/webqtl/collection/BatchSubmitSelectionPage.py
new file mode 100755
index 00000000..743606b2
--- /dev/null
+++ b/web/webqtl/collection/BatchSubmitSelectionPage.py
@@ -0,0 +1,225 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#BatchSubmitSelectionPage.py
+
+import string
+import time
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from AddToSelectionPage import AddToSelectionPage
+
+
+#########################################
+# batch submission result Page
+#########################################
+class BatchSubmitSelectionPage(AddToSelectionPage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+ if not fd.genotype:
+ fd.readGenotype()
+
+ heading = 'Batch Submission'
+
+ self.batchDataFile = fd.formdata.getvalue('batchdatafile')
+ if not self.batchDataFile:
+ templatePage.__init__(self, fd)
+ detail = ['The file you choose to import from doesn\'t exist.']
+ self.error(heading=heading,detail=detail)
+ return
+ self.batchDataFile = string.replace(self.batchDataFile, '\r', '\n')
+ self.batchDataFile = string.replace(self.batchDataFile, '\n\n', '\n')
+ self.batchDataFile = string.split(self.batchDataFile, '\n')
+ self.batchDataFile = map(string.strip, self.batchDataFile)
+
+ traitNames, strainNames, traitValues, SE, NStrain = self.parseDataFile()
+ strainIds = []
+
+ #print 'Content-type: text/html\n'
+ #print len(traitNames), len(strainNames) , len(strainIds), len(traitValues) , len(SE), "
", len(NStrain)
+ #return
+
+ try:
+
+ if not traitNames or not strainNames or not traitValues or len(traitNames) != len(traitValues) or len(traitNames) != len(SE) or len(traitNames) != len(NStrain):
+ raise 'ValueError'
+ for item in traitValues:
+ if len(strainNames) != len(item):
+ raise 'ValueError'
+ for item in SE:
+ if len(strainNames) != len(item):
+ raise 'ValueError'
+ for item in NStrain:
+ if len(strainNames) != len(item):
+ raise 'ValueError'
+ for item in strainNames:
+ self.cursor.execute('''Select
+ Strain.Id
+ from Strain, StrainXRef,InbredSet
+ where
+ Strain.Name = "%s" AND
+ StrainXRef.StrainId = Strain.Id AND
+ StrainXRef.InbredSetId = InbredSet.Id AND
+ InbredSet.Name = "%s"
+ ''' % (item, fd.RISet))
+ strainId = self.cursor.fetchone()[0]
+ strainIds.append(strainId)
+ except:
+ templatePage.__init__(self, fd)
+ detail = ['The format of the file is incorrect, or it contains unknown strains.']
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.searchResult = []
+ self.addToTable(traitNames, strainNames,strainIds, traitValues,SE, NStrain, fd)
+
+ if self.genSelection(fd=fd):
+ self.writeHTML(fd)
+
+ def parseDataFile(self):
+ rchSartPos = 0
+ header = []
+ traits = []
+ data = []
+ se = []
+ nstrain = []
+ strains = []
+
+ if 1:
+ for line in self.batchDataFile:
+ line = line.strip()
+ if line == '' or line[0] == '#':
+ continue
+
+ columns = string.split(line, '\t')
+ columns = map(string.strip, columns)
+
+ if rchSartPos == 'column':
+ strains.append(columns[0])
+ tdata = map(webqtlUtil.StringAsFloat,columns[1:])
+ for j, item in enumerate(tdata):
+ if posIdx[j][0] == 'data':
+ data[posIdx[j][1]].append(item)
+ elif posIdx[j][0] == 'n':
+ if item != None:
+ nstrain[posIdx[j][1]].append(int(item))
+ else:
+ nstrain[posIdx[j][1]].append(item)
+ else:
+ se[posIdx[j][1]].append(item)
+
+ elif rchSartPos == 'row':
+ if columns[0].lower() == 'se':
+ se.append(map(webqtlUtil.StringAsFloat,columns[1:]))
+ elif columns[0].lower() == 'n':
+ nstrain.append(map(webqtlUtil.IntAsFloat,columns[1:]))
+ else:
+ while (len(data) > len(se)):
+ se.append([None] * len(data[-1]))
+ while (len(data) > len(nstrain)):
+ nstrain.append([None] * len(data[-1]))
+ header.append(columns[0])
+ data.append(map(webqtlUtil.StringAsFloat,columns[1:]))
+ elif columns[0] == '@format=column':
+ rchSartPos = 'column'
+ posIdx = []
+ j = 0
+ for item in columns[1:]:
+ #assign column type
+ if string.lower(item) == 'se':
+ posIdx.append(('se',j-1))
+ elif string.lower(item) == 'n':
+ posIdx.append(('n',j-1))
+ else:
+ header.append(item)
+ posIdx.append(('data',j))
+ j += 1
+
+ for i in range(len(header)):
+ data.append([])
+ se.append([])
+ nstrain.append([])
+ elif columns[0] == '@format=row':
+ rchSartPos = 'row'
+ strains = columns[1:]
+ else:
+ pass
+ #modify
+ for i in range(len(se)):
+ if se[i] == []:
+ se[i] = [None] * len(data[-1])
+ for i in range(len(nstrain)):
+ if nstrain[i] == []:
+ nstrain[i] = [None] * len(data[-1])
+ if len(data) > len(se):
+ se.append([None] * len(data[-1]))
+ if len(data) > len(nstrain):
+ nstrain.append([None] * len(data[-1]))
+
+ return header,strains,data,se, nstrain
+ else:
+ return [],[],[],[], []
+
+
+ #XZ, add items to self.searchResult
+ def addToTable(self, traitNames, strainNames,strainIds, traitValues, SE, NStrain, fd):
+ self.cursor.execute('delete Temp, TempData from Temp, TempData where Temp.DataId = TempData.Id and UNIX_TIMESTAMP()-UNIX_TIMESTAMP(CreateTime)>%d;' % webqtlConfig.MAXLIFE)
+
+ i = 0
+ for trait in traitNames:
+ ct0 = time.localtime(time.time())
+ ct = time.strftime("%B/%d %H:%M:%S",ct0)
+ if trait == '':
+ trait = "Unnamed Trait"
+ user_ip = fd.remote_ip
+ newDescription = '%s entered at %s from IP %s' % (trait,ct,user_ip)
+ newProbeSetID = webqtlUtil.genRandStr('Usr_TMP_')
+
+ self.cursor.execute('SelecT max(id) from TempData')
+ try:
+ DataId = self.cursor.fetchall()[0][0] + 1
+ except:
+ DataId = 1
+
+ self.cursor.execute('Select Id from InbredSet where Name = "%s"' % fd.RISet)
+ InbredSetId = self.cursor.fetchall()[0][0]
+
+ self.cursor.execute('insert into Temp(Name,description, createtime,DataId,InbredSetId,IP) values(%s,%s,Now(),%s,%s,%s)' ,(newProbeSetID, newDescription, DataId,InbredSetId,user_ip))
+
+ for k in range(len(traitValues[i])):
+ if traitValues[i][k] != None:
+ self.cursor.execute('insert into TempData(Id, StrainId, value, SE, NStrain) values(%s, %s, %s, %s, %s)' , (DataId, strainIds[k], traitValues[i][k],SE[i][k],NStrain[i][k]))
+
+ self.searchResult.append('Temp::%s' % newProbeSetID)
+ i += 1
+
diff --git a/web/webqtl/collection/DisplaySelectionPage.py b/web/webqtl/collection/DisplaySelectionPage.py
new file mode 100755
index 00000000..02d4d4b8
--- /dev/null
+++ b/web/webqtl/collection/DisplaySelectionPage.py
@@ -0,0 +1,51 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#DisplaySelectionPage.py
+
+from base.templatePage import templatePage
+from AddToSelectionPage import AddToSelectionPage
+
+#########################################
+# Display Selection Page
+#########################################
+class DisplaySelectionPage(AddToSelectionPage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if not fd.genotype:
+ fd.readGenotype()
+
+ self.searchResult = []
+
+ self.genSelection(fd=fd)
+
+ self.writeHTML(fd)
diff --git a/web/webqtl/collection/ExportSelectionDetailInfoPage.py b/web/webqtl/collection/ExportSelectionDetailInfoPage.py
new file mode 100755
index 00000000..69f293b2
--- /dev/null
+++ b/web/webqtl/collection/ExportSelectionDetailInfoPage.py
@@ -0,0 +1,197 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#ExportSelectionDetailInfoPage.py
+
+import string
+from htmlgen import HTMLgen2 as HT
+import os
+import time
+import pyXLWriter as xl
+
+import reaper
+
+from base import webqtlConfig
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base.webqtlTrait import webqtlTrait
+
+
+#########################################
+# Export Selection DetailInfo Page
+#########################################
+class ExportSelectionDetailInfoPage(templatePage):
+
+ 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
+ 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)
+
+
diff --git a/web/webqtl/collection/ExportSelectionPage.py b/web/webqtl/collection/ExportSelectionPage.py
new file mode 100755
index 00000000..df401e9e
--- /dev/null
+++ b/web/webqtl/collection/ExportSelectionPage.py
@@ -0,0 +1,67 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#ExportSelectionPage.py
+
+import string
+import time
+
+from base.templatePage import templatePage
+
+
+#########################################
+# Export Selection Page
+#########################################
+class ExportSelectionPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ collectionName = '%s_Select' % fd.RISet
+
+ try:
+ preSelection = fd.input_session_data[collectionName]
+ preSelection = list(string.split(preSelection,','))
+ except:
+ preSelection = []
+
+ for item in preSelection:
+ if not item:
+ preSelection.remove(item)
+
+ if preSelection:
+ self.content_type = 'application/txt'
+ self.content_disposition = 'attachment; filename=%s' % (fd.RISet+'_export-%s.txt' % time.strftime("%y-%m-%d-%H-%M"))
+ self.attachment += fd.RISet+"\n"
+ for item in preSelection:
+ self.attachment += item+"\n"
+ else:
+ heading = 'Export Collection'
+ detail = ['This collection is empty. No trait could be exported.']
+ self.error(heading=heading,detail=detail)
+
+
diff --git a/web/webqtl/collection/ImportSelectionPage.py b/web/webqtl/collection/ImportSelectionPage.py
new file mode 100755
index 00000000..0702509b
--- /dev/null
+++ b/web/webqtl/collection/ImportSelectionPage.py
@@ -0,0 +1,92 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#ImportSelectionPage.py
+
+import string
+
+from base.templatePage import templatePage
+from AddToSelectionPage import AddToSelectionPage
+
+
+#########################################
+# Import Selection Page
+#########################################
+class ImportSelectionPage(AddToSelectionPage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if not fd.genotype:
+ fd.readGenotype()
+
+ self.importFile = fd.formdata.getvalue('importfile')
+ if not self.importFile:
+ templatePage.__init__(self, fd)
+ heading = 'Import Collection'
+ detail = ['The file you choose to import from doesn\'t exist.']
+ self.error(heading=heading,detail=detail)
+ return
+ self.importFile = string.split(self.importFile, '\n')
+
+ RISetLocate = 0
+ self.searchResult = []
+ for line in self.importFile:
+ if line and line[0] != '#':
+ if not RISetLocate:
+ RISetLocate = line
+ if RISetLocate != fd.RISet:
+ templatePage.__init__(self, fd)
+ heading = 'Import Collection'
+ detail = ['The file you choose to import from doesn\'t contain %s selection.' % fd.RISet]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ self.searchResult.append(line)
+
+ if not self.searchResult:
+ templatePage.__init__(self, fd)
+ heading = 'Import Collection'
+ detail = ['The file you choose to import from is empty.']
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.importMethod = fd.formdata.getvalue('importmethod')
+
+ if self.importMethod == 'replace':
+ checkPreSelection = 0
+ else:
+ checkPreSelection = 1
+
+ if self.genSelection(fd=fd, checkPreSelection = checkPreSelection):
+ self.writeHTML(fd)
+
+
+
diff --git a/web/webqtl/collection/RemoveSelectionPage.py b/web/webqtl/collection/RemoveSelectionPage.py
new file mode 100755
index 00000000..b9560c6b
--- /dev/null
+++ b/web/webqtl/collection/RemoveSelectionPage.py
@@ -0,0 +1,108 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+
+
+import string
+
+from base.templatePage import templatePage
+from base.webqtlTrait import webqtlTrait
+from AddToSelectionPage import AddToSelectionPage
+
+#########################################
+# Remove Selection Page
+#########################################
+class RemoveSelectionPage(AddToSelectionPage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if not fd.genotype:
+ fd.readGenotype()
+
+ self.searchResult = fd.formdata.getvalue('searchResult')
+ if self.searchResult:
+ pass
+ else:
+ templatePage.__init__(self, fd)
+ heading = 'Remove Selections'
+ detail = ['You need to select at least one trait to remove from your selection.']
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.genSelection(fd=fd)
+ self.writeHTML(fd)
+
+
+
+ def genSelection(self, fd=None):
+ collectionName = '%s_Select' % fd.RISet
+
+ try:
+ preSelection = fd.input_session_data[collectionName]
+ preSelection = list(string.split(preSelection,','))
+ except:
+ preSelection = []
+
+ if type("1") == type(self.searchResult):
+ self.searchResult = [self.searchResult]
+
+ if preSelection:
+ for item in self.searchResult:
+ try:
+ preSelection.remove(item)
+ except:
+ pass
+ self.searchResult = preSelection[:]
+
+ if not self.searchResult:
+ self.session_data_changed[collectionName] = ""
+ return
+
+ #self.searchResult.sort()
+ for item in self.searchResult:
+ if not item:
+ self.searchResult.remove(item)
+
+ searchResult2 = []
+ self.theseTraits = []
+ for item in self.searchResult:
+ try:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo(QTL=1)
+ self.theseTraits.append(thisTrait)
+ searchResult2.append(item)
+ except:
+ pass
+
+ allTraitStr = string.join(searchResult2,',')
+
+ self.session_data_changed[collectionName] = allTraitStr
+
diff --git a/web/webqtl/collection/__init__.py b/web/webqtl/collection/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/compareCorrelates/MultipleCorrelationPage.py b/web/webqtl/compareCorrelates/MultipleCorrelationPage.py
new file mode 100755
index 00000000..6a464ab6
--- /dev/null
+++ b/web/webqtl/compareCorrelates/MultipleCorrelationPage.py
@@ -0,0 +1,108 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base.webqtlTrait import webqtlTrait
+from base import webqtlConfig
+import multitrait
+
+# XZ, 09/09/2008: After adding several traits to collection, click "Compare Correlates" button,
+# XZ, 09/09/2008: This class will generate what you see.
+# XZ, 09/09/2008: This class just collect the input, then pass them to multitrait.py
+#########################################
+# Multiple Correlation Page
+#########################################
+class MultipleCorrelationPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+ if not fd.genotype:
+ fd.readData()
+
+ self.searchResult = fd.formdata.getvalue('searchResult')
+ if not self.searchResult:
+ heading = 'Compare Correlates'
+ detail = ['You need to select at least two traits in order to generate correlation matrix.']
+ self.error(heading=heading,detail=detail)
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+ if type("1") == type(self.searchResult):
+ self.searchResult = [self.searchResult]
+
+ if self.searchResult:
+ if len(self.searchResult) > 100:
+ heading = 'Compare Correlates'
+ detail = ['In order to display Compare Correlates properly, Do not select more than %d traits for Compare Correlates.' % 100]
+ self.error(heading=heading,detail=detail)
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+ else:
+ pass
+
+ traitList = []
+ for item in self.searchResult:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo()
+ traitList.append(thisTrait)
+ else:
+ heading = 'Compare Correlates'
+ detail = [HT.Font('Error : ',color='red'),HT.Font('Error occurs while retrieving data from database.',color='black')]
+ self.error(heading=heading,detail=detail)
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+
+
+ ##########
+ filename= webqtlUtil.genRandStr("mult_")
+ fp = open(webqtlConfig.IMGDIR+filename, 'wb')
+ fp.write('%s\n' % fd.RISet)
+ for thisTrait in traitList:
+ fp.write("%s,%s,%s\n" % (thisTrait.db.type,thisTrait.db.id,thisTrait.name))
+ fp.close()
+ fd.formdata["filename"] = filename
+
+ params = {"filename":filename, "targetDatabase":"",
+ "threshold":0.5, "subsetSize":10,
+ "correlation":"pearson", "subsetCount":10,
+ "firstRun":"1"}
+ results = []
+ txtOutputFileName = ""
+
+ self.dict['body'] = multitrait.TraitCorrelationPage(fd, params, self.cursor, traitList, results,
+ fd.RISet,txtOutputFileName).dict['body']
+ self.dict['title'] = 'Compare Correlates'
+
+
+
+
diff --git a/web/webqtl/compareCorrelates/__init__.py b/web/webqtl/compareCorrelates/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/compareCorrelates/correlation.py b/web/webqtl/compareCorrelates/correlation.py
new file mode 100755
index 00000000..f2ea55b3
--- /dev/null
+++ b/web/webqtl/compareCorrelates/correlation.py
@@ -0,0 +1,359 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+# correlation.py
+# functions for computing correlations for traits
+#
+# Originally, this code was designed to compute Pearson product-moment
+# coefficents. The basic function calcPearson scans the strain data
+# for the two traits and drops data for a strain unless both traits have it.
+# If there are less than six strains left, we conclude that there's
+# insufficent data and drop the correlation.
+#
+# In addition, this code can compute Spearman rank-order coefficents using
+# the calcSpearman function.
+
+#Xiaodong changed the dependancy structure
+import numarray
+import numarray.ma as MA
+import time
+
+import trait
+
+# strainDataUnion : StrainData -> StrainData -> array, array
+def strainDataUnion(s1, s2):
+ # build lists of values that both have
+ # and make sure that both sets of values are in the same order
+ s1p = []
+ s2p = []
+ sortedKeys = s1.keys()
+ sortedKeys.sort()
+ for s in sortedKeys:
+ if s2.has_key(s):
+ s1p.append(s1[s])
+ s2p.append(s2[s])
+
+ return (numarray.array(s1p, numarray.Float64),
+ numarray.array(s2p, numarray.Float64))
+
+# calcCorrelationHelper : array -> array -> float
+def calcCorrelationHelper(s1p, s2p):
+ # if the traits share less than six strains, then we don't
+ # bother with the correlations
+ if len(s1p) < 6:
+ return 0.0
+
+ # subtract by x-bar and y-bar elementwise
+ #oldS1P = s1p.copy()
+ #oldS2P = s2p.copy()
+
+ s1p = (s1p - numarray.average(s1p)).astype(numarray.Float64)
+ s2p = (s2p - numarray.average(s2p)).astype(numarray.Float64)
+
+ # square for the variances
+ s1p_2 = numarray.sum(s1p**2)
+ s2p_2 = numarray.sum(s2p**2)
+
+ try:
+ corr = (numarray.sum(s1p*s2p)/
+ numarray.sqrt(s1p_2 * s2p_2))
+ except ZeroDivisionError:
+ corr = 0.0
+
+ return corr
+
+# calcSpearman : Trait -> Trait -> float
+def calcSpearman(trait1, trait2):
+ s1p, s2p = strainDataUnion(trait1.strainData,
+ trait2.strainData)
+ s1p = rankArray(s1p)
+ s2p = rankArray(s2p)
+ return calcCorrelationHelper(s1p, s2p)
+
+# calcPearson : Trait -> Trait -> float
+def calcPearson(trait1, trait2):
+ # build lists of values that both have
+ # and make sure that both sets of values are in the same order
+ s1p, s2p = strainDataUnion(trait1.strainData,
+ trait2.strainData)
+
+ return calcCorrelationHelper(s1p, s2p)
+
+# buildPearsonCorrelationMatrix: (listof n traits) -> int s -> n x s matrix, n x s matrix
+#def buildPearsonCorrelationMatrix(traits, sc):
+# dim = (len(traits), sc)
+# matrix = numarray.zeros(dim, MA.Float64)
+# testMatrix = numarray.zeros(dim, MA.Float64)
+
+# for i in range(len(traits)):
+# sd = traits[i].strainData
+# for key in sd.keys():
+# matrix[i,int(key) - 1] = sd[key]
+# testMatrix[i,int(key) - 1] = 1
+
+def buildPearsonCorrelationMatrix(traits, commonStrains):
+ dim = (len(traits), len(commonStrains))
+ matrix = numarray.zeros(dim, MA.Float64)
+ testMatrix = numarray.zeros(dim, MA.Float64)
+
+ for i in range(len(traits)):
+ sd = traits[i].strainData
+ keys = sd.keys()
+ for j in range(0, len(commonStrains)):
+ if keys.__contains__(commonStrains[j]):
+ matrix[i,j] = sd[commonStrains[j]]
+ testMatrix[i,j] = 1
+
+ return matrix, testMatrix
+
+# buildSpearmanCorrelationMatrix: (listof n traits) -> int s -> n x s matrix, n x s matrix
+def buildSpearmanCorrelationMatrix(traits, sc):
+ dim = (len(traits), sc)
+ matrix = numarray.zeros(dim, MA.Float64)
+ testMatrix = numarray.zeros(dim, MA.Float64)
+
+ def customCmp(a, b):
+ return cmp(a[1], b[1])
+
+ for i in range(len(traits)):
+ # copy strain data to a temporary list and turn it into
+ # (strain, expression) pairs
+ sd = traits[i].strainData
+ tempList = []
+ for key in sd.keys():
+ tempList.append((key, sd[key]))
+
+ # sort the temporary list by expression
+ tempList.sort(customCmp)
+
+ for j in range(len(tempList)):
+ # k is the strain id minus 1
+ # 1-based strain id -> 0-based column index
+ k = int(tempList[j][0]) - 1
+
+ # j is the rank of the particular strain
+ matrix[i,k] = j
+
+ testMatrix[i,k] = 1
+
+ return matrix, testMatrix
+
+def findLargestStrain(traits, sc):
+ strainMaxes = []
+ for i in range(len(traits)):
+ keys = traits[i].strainData.keys()
+ strainMaxes.append(max(keys))
+
+ return max(strainMaxes)
+
+def findCommonStrains(traits1, traits2):
+ commonStrains = []
+ strains1 = []
+ strains2 = []
+
+ for trait in traits1:
+ keys = trait.strainData.keys()
+ for key in keys:
+ if not strains1.__contains__(key):
+ strains1.append(key)
+
+ for trait in traits2:
+ keys = trait.strainData.keys()
+ for key in keys:
+ if not strains2.__contains__(key):
+ strains2.append(key)
+
+ for strain in strains1:
+ if strains2.__contains__(strain):
+ commonStrains.append(strain)
+
+ return commonStrains
+
+def calcPearsonMatrix(traits1, traits2, sc, strainThreshold=6,
+ verbose = 0):
+ return calcMatrixHelper(buildPearsonCorrelationMatrix,
+ traits1, traits2, sc, strainThreshold,
+ verbose)
+
+def calcProbeSetPearsonMatrix(cursor, freezeId, traits2, strainThreshold=6,
+ verbose = 0):
+
+ cursor.execute('select ProbeSetId from ProbeSetXRef where ProbeSetFreezeId = %s order by ProbeSetId' % freezeId)
+ ProbeSetIds = cursor.fetchall()
+
+ results = []
+ i=0
+ while i listof float
+# to generate a companion list to alof with
+# the actual value of each element replaced by the
+# value's rank
+def rankArray(floatArray):
+ # first we save the original index of each element
+ tmpAlof = []
+ returnArray = numarray.zeros(len(floatArray), numarray.Float64)
+ i = 0
+ for i in range(len(floatArray)):
+ tmpAlof.append((i,floatArray[i]))
+
+ # now we sort by the data value
+ def customCmp(a,b): return cmp(a[1],b[1])
+ tmpAlof.sort(customCmp)
+
+ # finally we use the new rank data to populate the
+ # return array
+ for i in range(len(floatArray)):
+ returnArray[tmpAlof[i][0]] = i+1
+
+ return returnArray
diff --git a/web/webqtl/compareCorrelates/htmlModule.py b/web/webqtl/compareCorrelates/htmlModule.py
new file mode 100755
index 00000000..ebba3b86
--- /dev/null
+++ b/web/webqtl/compareCorrelates/htmlModule.py
@@ -0,0 +1,279 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import sys
+import string
+import os
+import MySQLdb
+import cgi
+
+from htmlgen import HTMLgen2 as HT
+
+from base import webqtlConfig
+
+
+# XZ 08/14/2008: When I tried to replace 'from webqtlConfig import *' with 'import webqtlConfig'
+# XZ 08/14/2008: I found some problems. I discussed with Hongqiang and the below is conclusion.
+# XZ 08/14/2008: The program uses webqtlConfig.DB_NAME, webqtlConfig.MYSQL_SERVER and so on
+# XZ 08/14/2008: without 'import webqtlConfig'. This program will not work.
+# XZ 08/14/2008: CONFIG_htmlpath doesn't exist in webqtlConfig.py
+# XZ 08/14/2008: Hongqian said this was done by Fan Zhang, and this program was not tested.
+# XZ 08/14/2008: So nobody realize these bugs.
+
+# XZ, 09/09/2008: This function is not called any where.
+# XZ, 09/09/2008: Actually, I don't think this function works.
+def genHeaderFooter(i=1,title='',basehref='',js1='',js2='',layer='',body=''):
+ """
+ generate footer and header HTML code
+ default is header
+ i = 0 is footer+header
+ i = 1 is header
+ i = 2 is footer
+ """
+ try:
+ temp_file = CONFIG_htmlpath + 'beta-template.html'
+ fp = open(temp_file, 'rb')
+ template = fp.read()
+ fp.close()
+ template = template % (title,basehref,js1,js2,layer,body, "")
+ header,footer = string.split(template,'')
+ if i == 0:
+ return header + footer
+ elif i == 1:
+ return header
+ elif i == 2:
+ return footer
+ else:
+ return ""
+ except:
+ if i == 0:
+ return "header + footer"
+ elif i == 1:
+ return "header"
+ elif i == 2:
+ return "footer"
+ else:
+ return ""
+
+# XZ, 09/09/2008: This function is only used in multitrait.py where it is called with value assigned to db.
+# XZ, 09/09/2008: So the try-except block is not executed.
+# XZ, 09/09/2008: This explains why no error was generated even without 'import webqtlConfig'
+def genDatabaseMenu(db = None, public =1, RISetgp = 'BXD', selectname = 'database', selected = ""):
+ """
+ generate database Menu
+ public = 0 : search3.html databases Menu
+ public = 1 : search.html databases Menu
+ """
+ if not db:
+ try:
+ # import MySQLdb
+ # con = MySQLdb.Connect(db='db_webqtl')
+ # Modified by Fan Zhang
+ con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD)
+ db = con.cursor()
+ except:
+ return "Connect MySQL Server Error"
+ else:
+ pass
+
+ databaseMenu = HT.Select(name=selectname)
+ nmenu = 0
+
+ # here's a hack: bxd and bxd300 can be correlated against each other
+ # if either of those are the group, we put in special SQL that pulls both
+ if RISetgp in ("BXD", "BXD300"):
+ ibsNameQry = '(InbredSet.Name = "BXD" OR InbredSet.Name = "BXD300")'
+ else:
+ ibsNameQry = 'InbredSet.Name = "%s"' % RISetgp
+
+ #Publish Database
+ db.execute('''
+ SelecT
+ PublishFreeze.FullName,
+ PublishFreeze.Name
+ from
+ PublishFreeze,
+ InbredSet
+ where
+ PublishFreeze.InbredSetId = InbredSet.Id and
+ %s
+ ''' % ibsNameQry)
+ for item in db.fetchall():
+ databaseMenu.append(item)
+ nmenu += 1
+
+ #Genome Database
+ db.execute('''
+ SelecT
+ GenoFreeze.FullName,
+ GenoFreeze.Name
+ from
+ GenoFreeze,InbredSet
+ where
+ GenoFreeze.InbredSetId = InbredSet.Id and
+ %s
+ ''' % ibsNameQry)
+ for item in db.fetchall():
+ databaseMenu.append(item)
+ nmenu += 1
+
+ #Microarray Database
+ db.execute('SelecT Id, Name from Tissue')
+ for item in db.fetchall():
+ TId, TName = item
+ databaseMenuSub = HT.Optgroup(label = '%s ------' % TName)
+ db.execute('''
+ SelecT
+ ProbeSetFreeze.FullName,
+ ProbeSetFreeze.Name
+ from
+ ProbeSetFreeze,
+ ProbeFreeze,
+ InbredSet
+ where
+ ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and
+ ProbeFreeze.TissueId = %d and
+ ProbeSetFreeze.public > %d and
+ ProbeFreeze.InbredSetId = InbredSet.Id and
+ %s
+ order by
+ ProbeSetFreeze.CreateTime desc,
+ ProbeSetFreeze.AvgId
+ ''' % (TId,public,ibsNameQry))
+ for item2 in db.fetchall():
+ databaseMenuSub.append(item2)
+ nmenu += 1
+ databaseMenu.append(databaseMenuSub)
+
+ if nmenu:
+ if selected:
+ databaseMenu.selected.append(selected)
+ return str(databaseMenu)
+ else:
+ return ''
+
+
+# XZ, 09/09/2008: This function is not called any where.
+# XZ, 09/09/2008: Actually, I don't think this function works.
+# XZ, 09/09/2008: There is no 'DataForm' file now. It should be webqtlForm.py
+def genRISample():
+ import glob
+ import reaper
+ import random
+ import math
+ import webqtlUtil
+ risets = filter(lambda X:X.find('F2')<0, map(os.path.basename, glob.glob(os.path.join(CONFIG_genodir, "*.geno"))))
+ risets = map(lambda X:X.split('.')[0], risets)
+ risets.remove("BayXSha")
+ risets.sort()
+ body = HT.Blockquote()
+ NPerRow = 6
+ for item in risets:
+ values = []
+ if item == 'AXBXA': item2='AXB/BXA'
+ elif item == 'HXBBXH': item2='HXB/BXH'
+ else: item2=item
+ body.append(HT.Paragraph(item2, Class='subtitle'))
+ tbl = HT.TableLite(Class="collap")
+ dataset = reaper.Dataset()
+ dataset.read(os.path.join(CONFIG_genodir, "%s.geno"%item))
+ prgy = webqtlUtil.ParInfo[item] + list(dataset.prgy)
+
+ mean = random.random()*100
+ variance = random.random()*500
+ variables = []
+ while len(variables) < len(prgy):
+ S = 2
+ while (S>=1):
+ U1= random.random()
+ U2= random.random()
+ V1= 2*U1-1.0
+ V2= 2*U2-1.0
+ S=V1*V1+V2*V2
+ X= math.sqrt(-2 * math.log(S) / S) * V1
+ Y= math.sqrt(-2 * math.log(S) / S) * V2
+ variables.append(mean + math.sqrt(variance) * X)
+ variables.append(mean + math.sqrt(variance) * Y)
+
+ tempTR = HT.TR()
+ for i, strain in enumerate(prgy):
+ if i and i%NPerRow==0:
+ tbl.append(tempTR)
+ tempTR = HT.TR()
+ if random.random() < 0.2:
+ variable = 'X'
+ else:
+ variable = "%2.3f" % variables[i]
+
+ tempTR.append(HT.TD(strain, Class="strains", width=80))
+ tempTR.append(HT.TD(variable, Class="values", width=60))
+ values.append(variable)
+
+ for j in range(NPerRow-i%NPerRow-1):
+ tempTR.append(HT.TD())
+ tbl.append(tempTR)
+ body.append(tbl)
+ body.append(HT.Paragraph("Copy the following line to paste into the GeneNetwork entry box:"))
+ body.append(HT.Code(string.join(values, " ")))
+ body.append(HT.HR(width="90%"))
+ return body
+
+if __name__ == "__main__":
+ if os.environ.has_key('SCRIPT_FILENAME'):
+ script_filename = os.environ['SCRIPT_FILENAME']
+ else:
+ script_filename = ''
+ #Used as cgi script
+ if script_filename and script_filename[-2:] == 'py':
+ print 'Content-type: text/html\n'
+ formdata = cgi.FieldStorage()
+ sys.stderr = sys.stdout
+ try:
+ getID = string.lower(formdata.getvalue('get'))
+ except:
+ getID = ''
+ #Used as command
+ else:
+ if len(sys.argv) >= 2:
+ getID = string.lower(sys.argv[1])
+ else:
+ getID = ''
+
+ if getID == 'headerfooter':
+ print genHeaderFooter(0)
+ elif getID == 'header':
+ print genHeaderFooter(1)
+ elif getID == 'footer':
+ print genHeaderFooter(2)
+ elif getID == 'databasemenu':
+ print genDatabaseMenu(public=0)
+ elif getID == 'datasample':
+ print genRISample()
+ else:
+ print genHeaderFooter(0)
+else:
+ pass
+
diff --git a/web/webqtl/compareCorrelates/multitrait.py b/web/webqtl/compareCorrelates/multitrait.py
new file mode 100755
index 00000000..047620af
--- /dev/null
+++ b/web/webqtl/compareCorrelates/multitrait.py
@@ -0,0 +1,1121 @@
+# multitrait.py
+# a tool to analyze the correlations between several different traits and the traits
+# in a given dataset
+#
+# Parameters:
+# correlation -- either "pearson" or "spearman" depending on which ones we want to use
+#
+# filename -- an input file containing the traits to analyze
+#
+# progress -- if set, this parameter outputs a static progress page
+# and uses a META redirect to trigger the real computation
+#
+# targetDatabaseType:
+# one of "ProbeSet", "Publish", "Genotype" depending on the type of database
+# we will use for the analysis
+#
+# targetDatabaseId:
+# the id (*Freeze.Id in the database) of the particular database we will analyze
+#
+# threshold -- a float between 0 and 1 to determine which coefficents we wil l consider
+#
+# firstRun -- either 0 or 1
+# whether to automatically pick reasonable defaults for the other three parameters
+#
+# outputType -- either "html" or "text"
+#
+# Author: Stephen Pitts
+# June 15, 2004
+
+#Xiaodong changed the dependancy structure
+
+import copy
+import sys
+import cgi
+import os
+import os.path
+import math
+import time
+import numarray
+import tempfile
+import string
+import cgitb #all tracebacks come out as HTMLified CGI,useful when we have a random crash in the middle
+
+from base import templatePage
+from base.webqtlTrait import webqtlTrait
+from utility import webqtlUtil
+from base import webqtlConfig
+import trait
+import correlation
+import htmlModule
+
+cgitb.enable()
+
+
+# where this program's data files are
+RootDir = webqtlConfig.IMGDIR # XZ, 09/10/2008: add module name 'webqtlConfig.'
+RootDirURL = "/image/" # XZ, 09/10/2008: This parameter is not used in this module
+
+tempfile.tempdir = RootDir
+tempfile.template = "multitrait"
+
+# MultitraitException: used if something goes wrong
+# maybe in the future we should make exceptions more granular
+class MultitraitException(Exception):
+ def __init__(self, message):
+ self.message = message
+
+ def __repr__(self):
+ return "MultitraitException: %s" % self.message
+
+# buildParamDict: Cursor -> ParamDict
+# to process and validate CGI arguments
+# see the comment at the top of this file for valid cgi
+# parameters
+def buildParamDict(cursor, fd):
+ params = {}
+ fs = fd.formdata #cgi.FieldStorage()
+ params["progress"] = fs.getfirst("progress", "0")
+ params["filename"] = fs.getfirst("filename", "")
+ if params["filename"] == "":
+ raise MultitraitException("Required parameter filename missing.")
+
+ params["targetDatabase"] = fs.getfirst("targetDatabase", "U74Av2RMA_Raw_ProbeSet_March04")
+ params["firstRun"] = webqtlUtil.safeInt(fs.getfirst("firstRun", "0"),0)
+ params["threshold"] = webqtlUtil.safeFloat(fs.getfirst("threshold", "0.5"), 0.5)
+ params["subsetSize"] = webqtlUtil.safeInt(fs.getfirst("subsetSize", "10"), 10)
+
+ if params["subsetSize"] < -1:
+ params["subsetSize"] = -1
+
+ params["correlation"] = fs.getfirst("correlation", "pearson")
+ params["subsetCount"] = webqtlUtil.safeInt(fs.getfirst("subsetCount", 10), 10)
+
+ if params["subsetCount"] < -1:
+ params["subsetCount"] = -1
+
+ #params["outputType"] = fs.getfirst("outputType", "html")
+
+ #if params["outputType"] not in ("html", "text"):
+ # params["outputType"] = "html"
+
+ if params["correlation"] not in ("pearson", "spearman"):
+ params["correlation"] = "pearson"
+
+ params["correlationName"] = params["correlation"].capitalize()
+
+ # one of two cases:
+ # 1) We have just come from a submit, so there are a bunch of display*
+ # but no displaySets. Thus, the code down there converts the display*
+ # to displaySets so the GET request doesn't get too long
+ # 2) We have just been redirected from a progress page which already has
+ # a converted displaySets for us.
+
+ displaySets = webqtlUtil.safeInt(fs.getfirst("displaySets","0"), 0)
+
+ if displaySets == 0:
+ for key in fs.keys():
+ if key[:7] == "display":
+ #print "Hit display key %s " % key
+ try:
+ whichSet = int(key[7:])
+
+ # prevent malicious attacks
+ whichSet = min(whichSet, 512)
+ displaySets += pow(2, whichSet)
+
+ except ValueError: pass
+
+ params["displaySets"] = displaySets
+ #print "In the beginning, display sets was %s: %s " % (displaySets,
+ # str(binaryDecompose(displaySets)))
+
+ # if we are just gonna display a progress page, then there's no
+ # reason to look up detailed database information
+ #if params["progress"] == "1":
+ # return params
+
+ a,b = trait.dbNameToTypeId(cursor, params["targetDatabase"]) # XZ, 09/10/2008: add module name
+ params["targetDatabaseType"] = a
+ params["targetDatabaseId"] = b
+ params["targetDatabaseName"] = params["targetDatabase"]
+
+ return params
+
+# readInputFile: DB cursor -> string -> string, (arrayof Trait)
+def readInputFile(cursor, filename):
+ """
+ To read an input file with n lines in the following format
+ ,,
+ and retrieve and populate traits with appropriate data
+ from the database
+
+ Also, for our purposes. we store the database type and
+ database id in fields attached to the trait instances. We use
+ this information to generate Javascript popups with trait
+ information.
+
+ In addition, we read the strain of mice that the traits are
+ from so we can only show those databases to correlate against.
+ """
+ handle = open(filename)
+ line = handle.readline()
+ inbredSetName = line.strip()
+ line = handle.readline()
+ traits = []
+
+# XZ, 09/10/2008: In this while loop block, I changed the original variable name 'trait' to 'oneTrait'
+ while line != "":
+ line = line.strip()
+ dbType, dbId, tName = line.split(",")
+
+ if dbType == "ProbeSet":
+ oneTrait = trait.queryProbeSetTraitByName(cursor, tName) # XZ, 09/10/2008: add module name
+ oneTrait.populateDataId(cursor, dbId)
+ oneTrait.dbName = trait.dbTypeIdToName(cursor, dbType, dbId) # XZ, 09/10/2008: add module name
+ elif dbType == "Geno":
+ speciesId = trait.getSpeciesIdByDbTypeId(cursor, dbType, dbId)
+ oneTrait = trait.queryGenotypeTraitByName(cursor, speciesId, tName) # XZ, 09/10/2008: add module name
+ oneTrait.populateDataId(cursor, dbId)
+ oneTrait.dbName = trait.dbTypeIdToName(cursor, dbType, dbId) # XZ, 09/10/2008: add module name
+ elif dbType == "Publish":
+ oneTrait = trait.queryPublishTraitByName(cursor, dbId, tName) # XZ, 09/10/2008: add module name
+ oneTrait.populateDataId(cursor, dbId)
+ oneTrait.dbName = trait.dbTypeIdToName(cursor, dbType, dbId) # XZ, 09/10/2008: add module name
+ elif dbType == "Temp":
+ oneTrait = trait.queryTempTraitByName(cursor, tName) # XZ, 09/10/2008: add module name
+ oneTrait.populateDataId(cursor, dbId)
+ oneTrait.dbName = "Temp"
+
+ oneTrait.populateStrainData(cursor)
+ traits.append(oneTrait)
+
+ line = handle.readline()
+
+ return inbredSetName, traits
+
+# loadDatabase: Cursor -> ParamDict -> arrayof Trait
+def loadDatabase(cursor, p):
+ """
+ To load a set of traits as specified by the
+ targetDatabaseId
+ and targetDatabaseType parameters
+
+ Cursor should be a fastCursor from the webqtl library (i.e.
+ a MySQLdb SSCursor).
+
+ Calling populateStrainData 20,000 or so times on a ProbeSet
+ is really inefficent, so I wrote an optimized queryPopulatedProbeSetTraits
+ in the trait module that uses a join to get all of the rows in
+ bulk, store the resultset on the server, and do all sorts of nice buffering.
+ It's about two or three times faster.
+ """
+ if p["targetDatabaseType"] == "ProbeSet": # XZ, 09/10/2008: add module name
+ dbTraits = trait.queryPopulatedProbeSetTraits(cursor,
+ p["targetDatabaseId"])
+ elif p["targetDatabaseType"] == "Publish": # XZ, 09/10/2008: add module name
+ dbTraits = trait.queryPublishTraits(cursor,
+ p["targetDatabaseId"])
+ psd = trait.PublishTrait.populateStrainData
+ elif p["targetDatabaseType"] == "Geno": # XZ, 09/10/2008: add module name
+ dbTraits = trait.queryGenotypeTraits(cursor,
+ p["targetDatabaseId"])
+ psd = trait.GenotypeTrait.populateStrainData
+ else:
+ print "Unknown target database type %s" % p["targetDatabaseType"]
+
+ if p["targetDatabaseType"] != "ProbeSet":
+ map(psd, dbTraits, [cursor]*len(dbTraits))
+
+ return dbTraits
+
+def runProbeSetCorrelations(cursor, p, traits):
+ """
+ To run the correlations between the traits and the database.
+ This function computes a correlation coefficent between each
+ trait and every entry in the database, and partitions the database
+ into a disjoint array of arrays which it returns.
+
+ The length of the return array is 2^n, where n is the length of
+ the trait array. Which constitutent element a of the return array
+ a given trait ends up in is determined by the following formula
+ i = i_02^0 + ... + i_(n-1)2^(n-1)
+ where i_0 is 1 if corr(a,trait 0) >= threshold and 0 otherwise
+
+ Since most of the several thousand database traits will end up
+ with i=0, we don't return them, so the first element of the
+ return array will be empty.
+
+ A particular element of subarray j of the return array contains
+ a 2-tuple (trait,kvalues). The variable trait is obviously the
+ particular database trait that matches the user traits l_1, ..., l_m
+ to which subarray j corresponds. kvalues is a list of the correlation
+ values linking trait to l_1, ..., l_m, so the length of kvalues is
+ the number of 1s in the binary representation of j (there must be
+ a better way to describe this length).
+
+ The return array is an array of 2-tuples. The first element of
+ each tuple is the index of the particular subarray, and the second
+ element is the subarray itself. The array is sorted in descending
+ order by the number of 1's in the binary representation of the
+ index so the first few subarrays are the ones that correspond to
+ the largest sets. Each subarray is then sorted by the average of
+ the magnitude of the individual correlation values.
+ """
+
+ kMin = p["threshold"]
+ traitArrays = {}
+
+ # TODO: Add Spearman support
+ freezeId = p["targetDatabaseId"]
+ if p["correlation"] == "pearson":
+ correlations = correlation.calcProbeSetPearsonMatrix(cursor, freezeId, traits) #XZ, 09/10/2008: add module name
+ else:
+ correlations = correlation.calcProbeSetSpearmanMatrix(freezeId, traits) #XZ, 09/10/2008: add module name
+
+ # now we test all of the correlations in bulk
+ test = numarray.absolute(correlations)
+ test = numarray.greater_equal(test, kMin)
+ test = test.astype(numarray.Int8)
+ #print test
+
+ db = trait.queryProbeSetTraits(cursor, freezeId) #XZ, 09/10/2008: add module name
+ for i in range(len(db)):
+ cIndex = 0
+ prods = []
+ for j in range(len(traits)):
+ if test[i,j] == 1:
+ cIndex += pow(2, j)
+ prods.append(correlations[i,j])
+ if cIndex != 0:
+ if not traitArrays.has_key(cIndex):
+ traitArrays[cIndex] = []
+
+ traitArrays[cIndex].append((db[i], prods))
+
+
+ # sort each inner list of traitArrays
+ # so the matched traits appear in descending order by the
+ # average magnitude of the correlation
+ def customCmp(traitPair, traitPair2):
+ magAvg1 = numarray.average(map(abs, traitPair[1]))
+ magAvg2 = numarray.average(map(abs, traitPair2[1]))
+
+ # invert the sign to get descending order
+ return -cmp(magAvg1, magAvg2)
+
+ for traitArray in traitArrays.values():
+ traitArray.sort(customCmp)
+
+ # sort the outer list of traitArrays
+ traitArrays2 = []
+ i = 0
+ for key in traitArrays.keys():
+ a = traitArrays[key]
+ if len(a) > 0:
+ traitArrays2.append((key,a,len(binaryDecompose(key)),
+ len(a)))
+
+ # we sort by the number of 1's in the binary output
+ # and then by the size of the list, both in descending order
+ def customCmp2(aL,bL):
+ a = -cmp(aL[2], bL[2])
+ if a == 0:
+ return -cmp(aL[3], bL[3])
+ else:
+ return a
+
+ traitArrays2.sort(customCmp2)
+
+ return traitArrays2
+
+def runCorrelations(p, strainCount, traits, db):
+ """
+ To run the correlations between the traits and the database.
+ This function computes a correlation coefficent between each
+ trait and every entry in the database, and partitions the database
+ into a disjoint array of arrays which it returns.
+
+ The length of the return array is 2^n, where n is the length of
+ the trait array. Which constitutent element a of the return array
+ a given trait ends up in is determined by the following formula
+ i = i_02^0 + ... + i_(n-1)2^(n-1)
+ where i_0 is 1 if corr(a,trait 0) >= threshold and 0 otherwise
+
+ Since most of the several thousand database traits will end up
+ with i=0, we don't return them, so the first element of the
+ return array will be empty.
+
+ A particular element of subarray j of the return array contains
+ a 2-tuple (trait,kvalues). The variable trait is obviously the
+ particular database trait that matches the user traits l_1, ..., l_m
+ to which subarray j corresponds. kvalues is a list of the correlation
+ values linking trait to l_1, ..., l_m, so the length of kvalues is
+ the number of 1s in the binary representation of j (there must be
+ a better way to describe this length).
+
+ The return array is an array of 2-tuples. The first element of
+ each tuple is the index of the particular subarray, and the second
+ element is the subarray itself. The array is sorted in descending
+ order by the number of 1's in the binary representation of the
+ index so the first few subarrays are the ones that correspond to
+ the largest sets. Each subarray is then sorted by the average of
+ the magnitude of the individual correlation values.
+ """
+ kMin = p["threshold"]
+ traitArrays = {}
+
+ # TODO: Add Spearman support
+ if p["correlation"] == "pearson":
+ correlations = correlation.calcPearsonMatrix(db, traits, strainCount) #XZ, 09/10/2008: add module name
+ else:
+ correlations = correlation.calcSpearmanMatrix(db, traits, strainCount) #XZ, 09/10/2008: add module name
+
+ # now we test all of the correlations in bulk
+ test = numarray.absolute(correlations)
+ test = numarray.greater_equal(test, kMin)
+ test = test.astype(numarray.Int8)
+ #print test
+
+
+ for i in range(len(db)):
+ cIndex = 0
+ prods = []
+ for j in range(len(traits)):
+ if test[i,j] == 1:
+ cIndex += pow(2, j)
+ prods.append(correlations[i,j])
+ if cIndex != 0:
+ if not traitArrays.has_key(cIndex):
+ traitArrays[cIndex] = []
+
+ traitArrays[cIndex].append((db[i], prods))
+
+ # sort each inner list of traitArrays
+ # so the matched traits appear in descending order by the
+ # average magnitude of the correlation
+ def customCmp(traitPair, traitPair2):
+ magAvg1 = numarray.average(map(abs, traitPair[1]))
+ magAvg2 = numarray.average(map(abs, traitPair2[1]))
+
+ # invert the sign to get descending order
+ return -cmp(magAvg1, magAvg2)
+
+ for traitArray in traitArrays.values():
+ traitArray.sort(customCmp)
+
+ # sort the outer list of traitArrays
+ traitArrays2 = []
+ i = 0
+ for key in traitArrays.keys():
+ a = traitArrays[key]
+ if len(a) > 0:
+ traitArrays2.append((key,a,len(binaryDecompose(key)),
+ len(a)))
+
+ # we sort by the number of 1's in the binary output
+ # and then by the size of the list, both in descending order
+ def customCmp2(aL,bL):
+ a = -cmp(aL[2], bL[2])
+ if a == 0:
+ return -cmp(aL[3], bL[3])
+ else:
+ return a
+
+ traitArrays2.sort(customCmp2)
+
+ return traitArrays2
+
+
+# XZ, 09/09/2008: In multiple trait correlation result page,
+# XZ, 09/09/2008: click "Download a text version of the above results in CSV format"
+
+# TraitCorrelationText: a class to display trait correlations
+# as textual output
+class TraitCorrelationText:
+ # build a text shell to describe the given trait correlations
+ # this method sets self.output; use str(self) to actually
+ # get the text page
+ #
+ # traits is a list of traits and traitArray is a
+ # list of 3-tuples: index, traits', garbage
+ # where index is a binary-encoded description of which subset of
+ # traits the list traits' matches
+ #
+ # traits' is a list of 3-tuples as well: trait, correlations, garbage
+ # where trait is a particular trait and correlations is a list of float
+ # correlations (matching traits above)
+ def __init__(self, p, traits, traitArray):
+ output = "Correlation Comparison\n"
+ output += "from WebQTL and the University of Tennessee Health Science Center\n"
+ output += "initiated at " + time.asctime(time.gmtime()) + " UTC\n\n"
+
+ output += self.showOptionPanel(p)
+ output += self.showSelectedTraits(traits)
+ output += self.showSummaryCorrelationResults(p, traits, traitArray)
+ output += self.showDetailedCorrelationResults(p, traits, traitArray)
+
+ self.output = output
+
+ # showOptionPanel: ParamDict -> string
+ # to display the options used to run this correlation
+ def showOptionPanel(self, params):
+ output = "Correlation Comparison Options:\n"
+ output += "Target database,%s\n" % params["targetDatabase"]
+ output += "Correlation type,%s\n" % params["correlationName"]
+ output += "Threshold,%f\n" % params["threshold"]
+ #output += "Subsets to Show,%d\n" % params["subsetCount"]
+ #output += "Traits to Show Per Subset,%d\n\n" % params["subsetSize"]
+ return output
+
+ # showSelectedTraits: (listof Trait) -> string
+ # to display the traits compared with the database
+ # note: we can't use tabular output because the traits could be of
+ # different types and produce different fields
+ def showSelectedTraits(self, traits):
+ output = "Selected Traits:\n"
+ for trait in traits:
+ output += '"' + trait.longName() + '"' + "\n"
+ output += "\n"
+ return output
+
+ # showSummaryCorrelationResults: ParamDict -> (listof Trait) ->
+ # TraitArray -> string
+ # see comment for __init__ for a description of TraitArray
+ #
+ # to show a summary (sets and sizes) of the correlation results
+ # as well as an X to indicate whether they will be included
+ # in the detailed output
+ def showSummaryCorrelationResults(self, p, traits, traitArray):
+ output = "Correlation Comparison Summary:\n"
+
+ #if p["subsetCount"] != -1:
+ # ourSubsetCount = min(p["subsetCount"], len(traitArray))
+ #else:
+
+ ourSubsetCount = len(traitArray)
+
+ displayDecomposition = binaryDecompose(p["displaySets"])
+ for j in range(ourSubsetCount):
+ i = traitArray[j][0]
+ traitSubarray = traitArray[j][1]
+ if len(traitSubarray) == 0:
+ continue
+
+ targetTraits = decomposeIndex(traits, i)
+ traitDesc = string.join(map(trait.Trait.shortName, targetTraits), # XZ, 09/10/2008: add module name
+ ", ")
+ if j in displayDecomposition:
+ checked = "X"
+ else:
+ checked = ""
+
+ output += '"%s","%s","%d"\n' % (checked, traitDesc, len(traitSubarray))
+
+ output += "\n"
+ return output
+
+ # showDetailedCorrelationResults: ParamDict -> (listof Trait) ->
+ # TraitArray -> string
+ #
+ # to show a detailed list of the correlation results; that is,
+ # to completely enumerate each subset of traitArray using the
+ # filtering parameters in p
+ def showDetailedCorrelationResults(self, p, traits, traitArray):
+ output = "Correlation Comparison Details:\n"
+ displayDecomposition = binaryDecompose(p["displaySets"])
+ displayDecomposition.sort()
+
+ def formatCorr(c):
+ return "%.4f" % c
+
+ for j in displayDecomposition:
+ i = traitArray[j][0]
+ traitSubarray = traitArray[j][1]
+
+ if len(traitSubarray) == 0:
+ continue
+
+ targetTraits = decomposeIndex(traits, i)
+ extraColumnHeaders = map(trait.Trait.shortName, targetTraits) # XZ, 09/10/2008: add module name
+ traitDesc = string.join(extraColumnHeaders, ", ")
+
+ #if(p["subsetSize"] != -1 and len(traitSubarray) > p["subsetSize"]):
+ # traitDesc += ",(showing top %s of %s)" % (p["subsetSize"],
+ # len(traitSubarray))
+ # traitSubarray = traitSubarray[0:p["subsetSize"]]
+
+ output += "%s\n" % traitDesc
+ output += traitSubarray[0][0].csvHeader([], extraColumnHeaders)
+ output += "\n"
+ for oneTrait, corr in traitSubarray:#XZ, 09/10/2008: change original variable name 'trait' to 'oneTrait'
+ corr = map(formatCorr, corr)
+ output += oneTrait.csvRow([], corr) + "\n"
+
+ output += "\n"
+
+ return output
+
+ # __str__ : string
+ # to return self.output as the string representation of this page
+ # self.output is built in __init__
+ def __str__(self):
+ return self.output
+
+# TraitCorrelationPage: a class to display trait correlations
+# for now this is just one HTML file, so we don't even write it
+# to a temporary file somewhere
+class TraitCorrelationPage(templatePage.templatePage):
+ """
+ Using the templatePage class, we build an HTML shell for
+ the core data here: the trait correlation lists.
+
+ The way templatePage works, we build the page in pieces in
+ the __init__ method and later on use the inherited write
+ method to render the page.
+ """
+ def __init__(self, fd, p, cursor, traits, traitArray, inbredSetName, txtFilename):
+
+ templatePage.templatePage.__init__(self, fd)
+
+ self.dict["title"] = "Correlation Comparison"
+ self.dict["basehref"] = ""
+ # NL: deleted js1 content part, since it has not been used in this project
+ self.dict["js1"] = ""
+ self.dict["js2"] = ""
+
+ body = "
Correlation Comparison
"
+ body += "
Run at %s UTC
" % time.asctime(time.gmtime())
+ body += """
+
The correlation comparison tool identifies intersecting sets of traits that are
+correlated with your selections at a specified threshold. A correlation comparison
+involves the following steps:
+
+
+Correlate:
+Choose a Target Database, a Correlation Type, and a Correlation
+Threshold. For your initial correlation, leave Number of Subsets to Show and
+Traits to Show per Subset at their default values of 10. Using the Correlation
+Options panel, you can adjust the Correlation Threshold, Number of Subsets to
+Show, and Traits to Show per Subset.
+
+
+
+Add to Collection:
+You can use the check boxes in the Correlation
+Comparison Details panel and the buttons at the bottom of the page to add these
+results to your selections page for further analysis in WebQTL.
+
+
+
+Filter:
+Using the Correlation Comparison Summary panel, choose which
+subsets you would like to display for export. Note that if you change the
+parameters in the Correlation Options panel, you will need to re-apply your filter.
+
+
+
+Export:
+Once you are satisfied with your report, use the export link at
+the bottom of the page to save the report as a comma-separated (CSV) text file
+which you can then import into Excel or another tool. Note: the exported report
+will list all subsets in the summary view and only those traits in the subsets
+you have selected in the Filter step.
+
+
+"""
+
+# body += """
+#
The correlation
+# comparison tool identifies the intersecting sets of traits that are
+# correlated with your selections. A correlation comparison involves
+# the following steps:
+#
+#
Correlate: Choose a Target Database, a Correlation Type, and a Correlation Threshold.
+# For the initial correlation, leave Subsets to Show and Traits to Show per Subset
+# at their default values of 10.
+#
Refine Correlation: Using the Correlation Options panel,
+# adjust the Correlation Threshold, Subsets to Show, and Traits to
+# Show per Subset until you have a reasonable number of traits.
+#
Filter: Using the Correlation Comparison Summary panel, choose which subsets you would
+# like to see. Note that if you change the parameters in the Correlation Options panel, you will
+# loose the filter you have selected.
+#
Export: Once you are satisfied with your report, use the export
+# link at the bottom of the page to save the report as a comma-separated (CSV) text file which
+# you can then import into Excel or another tool. Note: the exported report
+# will show all subsets in the summary view and all traits in each subset you have
+# selected in the Filter step.
+#
Shopping Cart: In addition, you can use the
+# check boxes in the Correlation Comparison Details panel and the
+# buttons at the bottom of the page to add the traits you have found to the shopping cart.
+#
+#
+# """
+
+ body += self.showOptionPanel(p, cursor, inbredSetName)
+ body += self.showSelectedTraits(traits, p, inbredSetName)
+
+ if p["firstRun"] == 0:
+ body += self.showCorrelationResults(p, inbredSetName, traits, traitArray)
+
+ exportParams = copy.copy(p)
+ exportParams["outputType"] = "text"
+
+ body += ('''
+
Export these results
+
+ Download a text version of the above results in CSV format. This text version differs from
+ the version you see on this page in two ways. First, the summary view shows all subsets. Second, the details
+ view shows all traits in the subsets that you have selected.
+
+ '''
+ % txtFilename)
+
+
+
+ body += "
"
+ self.dict["body"] = body
+
+
+ # showOptionPanel: ParamDict -> Cursor -> String -> String
+ # to build an option panel for the multitrait correlation
+ # we expect the database list to be a list of 2-tuples
+ # the first element of each tuple is the short name
+ # and the second element of the tuple is the long name
+ def showOptionPanel(self, params, cursor, inbredSetName):
+ output = '''
+
Correlation Options
+
+ '''
+
+ return output
+
+ # showSelectedTraits: listof Trait -> string
+ # to show a list of the selected traits
+ def showSelectedTraits(self, traits, p, inbredSetName):
+ output = '''
+ "
+ return output
+
+
+ # showSummaryCorrelationResults
+ # show just the number of traits in each subarray
+ def showSummaryCorrelationResults(self, p, traits, traitArray):
+ output = '''
+
+ '''
+ return output
+
+ # showDetailedCorrelationResults
+ # actually show the traits in each subarray
+ def showDetailedCorrelationResults(self, p, inbredSetName, traits,
+ traitArray):
+ output = "
Correlation Comparison Details
"
+
+ # the hidden form below powers all of the JavaScript links,
+ # the shopping cart links, and the correlation plot links
+
+ output += '''
+
+ ''' % inbredSetName
+
+ return output
+
+ # showCorrelationResults: ParamDict -> listof Trait -> tupleof (int,arrayof trait) -> String
+ # to build an output display for the multitrait correlation results
+ def showCorrelationResults(self, p, inbredSetName, traits, traitArray):
+ output = '''
+
Correlation Comparison Summary
+
+ %s correlations were computed for each of the selected traits with each trait in
+ the %s database.
+ Subsets of database traits for which correlations were higher than %s
+ or lower than -%s are shown below based on which traits
+ they correlated highly with. The top %s subsets, ranked by the number of input traits that
+ they correspond with, are shown, and at most %s traits in each subset are shown.
+ No shared corrrelates were found with your given traits at this
+ threshold. You may wish to lower the correlation threshold or choose different traits.
+
+ """
+ else:
+ output += self.showSummaryCorrelationResults(p, traits, traitArray)
+ output += self.showDetailedCorrelationResults(p, inbredSetName,
+ traits, traitArray)
+
+ return output
+
+# decomposeIndex: (listof Trait) -> Int ->
+# (listof Trait)
+# to use i to partition T into a sublist
+# each bit in i controls the inclusion or exclusion of a trait
+def decomposeIndex(traits, i):
+ targetTraits = []
+
+ for j in range(len(traits)):
+ # look, mom, a bitwise and!
+ # expression below tests whether the jth bit is
+ # set in i
+ # see runCorrelation for how we decompose the
+ # array index
+ if (i & pow(2,j)) == pow(2,j):
+ targetTraits.append(traits[j])
+
+ return targetTraits
+
+# binaryDecompose: int -> (listof int)
+# to decompose a number into its constituent powers of 2
+# returns a list of the exponents a_1...a_n such that the input m
+# is m = 2^a_1 + ... + 2^a_n
+def binaryDecompose(n):
+ if n == 0:
+ return []
+
+ # we start with the highest power of 2 <= this number
+ # and work our way down, subtracting powers of 2
+ start = long(math.floor(math.log(n)/math.log(2)))
+
+ exponents = []
+ while start >= 0:
+ if n >= long(math.pow(2, start)):
+ n -= math.pow(2,start)
+ exponents.append(start)
+ start -= 1
+ return exponents
+
+# powerOf : int -> int -> boolean
+# to determine whether m is a power of n;
+# more precisely, whether there exists z in Z s.t.
+# n^z = m
+def powerOf(m, n):
+ trialZ = math.floor(math.log(m)/math.log(n))
+ return pow(n,trialZ) == m
+
+
+class compCorrPage(templatePage.templatePage):
+ def __init__(self,fd):
+ templatePage.templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ cursor = self.cursor
+ params = buildParamDict(cursor, fd)
+
+ # get the input data
+ inbredSetName, traits = readInputFile(cursor, RootDir + params["filename"])
+
+ # and what we are comparing the data to
+ dbTraits = []
+ if params["targetDatabaseType"] != "ProbeSet":
+ dbTraits = loadDatabase(cursor, params)
+
+
+ # run the comparison itself
+ strainCount = trait.queryStrainCount(cursor) # XZ, 09/10/2008: add module name
+ if params["targetDatabaseType"] == "ProbeSet":
+ results = runProbeSetCorrelations(cursor, params, traits)
+ else:
+ results = runCorrelations(params, strainCount, traits, dbTraits)
+
+ # try to be smart about what to output:
+ # we want to limit the number of traits shown, at least initially
+ # and since traitArray is already sorted with most interesting
+ # subsets first, we simply pick up the first 500 or so traits
+ # that we find
+ if params["displaySets"] == 0:
+ selectedTraits = 0
+ for j in range(len(results)):
+ #print "Scanning subarray %d" % j
+ if selectedTraits <= 200:
+ params["displaySets"] += pow(2, j)
+ selectedTraits += len(results[j][1])
+
+ traitList = []
+ for oneTrait in traits: # XZ, 09/10/2008: change the original variable name 'trait' to 'oneTrait'
+ traitName = oneTrait.dbName+'::'+oneTrait.name # XZ, 09/10/2008: change the original variable name 'trait' to 'oneTrait'
+ aTrait = webqtlTrait(cursor=self.cursor, fullname=traitName)
+ traitList.append(aTrait)
+
+ # and generate some output
+ txtOutputFilename = tempfile.mktemp()
+ txtOutputHandle = open(txtOutputFilename, "w")
+ txtOutput = TraitCorrelationText(params, traits, results)
+ txtOutputHandle.write(str(txtOutput))
+ txtOutputHandle.close()
+ txtOutputFilename = os.path.split(txtOutputFilename)[1]
+
+ self.dict['body'] = TraitCorrelationPage(fd, params, cursor, traitList,
+ results, inbredSetName,
+ txtOutputFilename).dict['body']
diff --git a/web/webqtl/compareCorrelates/trait.py b/web/webqtl/compareCorrelates/trait.py
new file mode 100755
index 00000000..ff1f8119
--- /dev/null
+++ b/web/webqtl/compareCorrelates/trait.py
@@ -0,0 +1,1074 @@
+#Trait.py
+#
+#--Individual functions are already annotated, more or less.
+#
+#Classes:
+#RawPoint
+#Trait
+#ProbeSetTrait
+#GenotypeTrait
+#PublishTrait
+#TempTrait
+#-KA
+
+# trait.py: a data structure to represent a trait
+import time
+import string
+
+CONFIG_pubMedLinkURL = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=%s&dopt=Abstract"
+
+# RawPoint: to store information about the relationship between two particular
+# traits
+# RawPoint represents directly the input file
+class RawPoint:
+ def __init__(self, i, j):
+ self.i = i
+ self.j = j
+
+ def __eq__(self, other):
+ return (self.i == other.i and
+ self.j == other.j and
+ self.spearman == other.spearman and
+ self.pearson == other.pearson)
+
+ def __str__(self):
+ return "(%s,%s,%s,%s)" % (self.i, self.j, self.spearman, self.pearson)
+
+def tdEscapeList(cols, align="left"):
+ """
+ A helper function used by tableRow
+ in Trait that will convert a list of strings into a set of
+ table cells enclosed by
%s
tags
+ """
+ html = ""
+ for col in cols:
+ html += '
%s
' % (align, col)
+ return html
+
+def thEscapeList(cols):
+ """
+ A helper function used by tableRowHeader
+ in Trait that will convert a list of strings into a set of
+ table cells enclosed by
%s
tags
+ """
+ html = ""
+ for col in cols:
+ html += "
%s
" % col
+ return html
+
+def commaEscapeList(cols):
+ """
+ A helper function used by csvHeader and csvRow.
+ Really it's just a wrapper for string.join
+ """
+ return '"' + string.join(cols, '","') + '"'
+
+
+class Trait:
+ """
+ A trait represents an attribute of an object. In the WebQTL database, traits are stored
+ as ProbeSets; that is, the average values of a set of probes are stored.
+ """
+ def __init__(self, id="", name="", description="", symbol="", href=""):
+ self.id = id
+ self.name = name
+ self.dbName = ""
+ self.symbol = symbol
+ self.href = href
+ self.strainData = {}
+
+ def populateDataId(self, cursor, freezeId):
+ """
+ Retrieve the dataId for trait data corresponding to the given database
+ The way to do this depends on the particular type of trait, so we leave implementation
+ to subclasses.
+ """
+ raise NotImplementedError
+
+ def populateStrainData(self, cursor):
+ """
+ Load this trait full of train data corresponding to the data id
+ The data id can either come from populateDataId
+ or can be set manually by the user of this class.
+ Xiaodong added: The way to do this depends on the particular type of trait,
+ so we leave implementation to subclasses.
+
+ """
+ raise NotImplementedError
+
+ def shortName(self):
+ """
+ To return a short name for this trait; this name should be
+ appropriate for a row or column title
+ """
+ return self.name
+
+ def nameNoDB(self):
+ """
+ To return only the short name without the database attached
+ """
+ strArray = self.shortName().split('::')
+
+ return strArray[1]
+
+ def datasetName(self):
+ """
+ To return only the name of the dataset
+ """
+ strArray = self.shortName().split('::')
+
+ return strArray[0].strip()
+
+ def longName(self):
+ """
+ To return a long name for this trait; this name should be
+ appropriate for a key to a table
+ """
+ return self.shortName()
+
+ def __str__(self):
+ return self.shortName()
+
+ def tableRowHelper(self, beforeCols, afterCols, color, thisRow):
+ """
+ tableRowHelper: (arrayof String) -. String
+ To generate a table row to represent this object, appending
+ the additional information in beforeCols and afterCols
+ to the beginning and the end
+ """
+ thisRow[0] = '%s' % (self.traitInfoLink(),
+ self.name)
+ html = '
' % color
+ html += tdEscapeList(beforeCols + thisRow)
+ html += tdEscapeList(afterCols, align="right")
+ html += "
"
+
+ return html
+
+
+ def header(self):
+ """
+ header: (listof String)
+ To generate a list of strings describing each piece of data
+ returned by row
+ """
+ raise NotImplementedError
+
+ def row(self):
+ """
+ row: (listof String)
+ To generate a list of strings describing this object. The
+ elements of this list should be described by header()
+ """
+ raise NotImplementedError
+
+ def tableRowHeader(self, beforeCols, afterCols, color):
+ """
+ tableRowHeader: (arrayof String) -> (arrayof String) -> String
+ To generate a table row header to represent this object,
+ appending the additional information in beforeCols and
+ afterCols to the beginning and end
+ """
+ html = '
' % color
+ html += thEscapeList(beforeCols + self.header() +
+ afterCols)
+ html += "
"
+ return html
+
+ def csvHeader(self, beforeCols, afterCols):
+ return commaEscapeList(beforeCols + self.header() + afterCols)
+
+ def csvRow(self, beforeCols, afterCols):
+ return commaEscapeList(beforeCols + self.row() + afterCols)
+
+
+ def traitInfoLink(self):
+ """
+ To build a trait info link to show information about this
+ trait. We assume that the database attribute is properly set
+ on the hidden form on the page where this link will go.
+ """
+ return "javascript:showDatabase2('%s','%s','')" % (self.dbName, self.name)
+
+# ProbeSetTrait: a trait with data from a probeset
+class ProbeSetTrait(Trait):
+ def __init__(self, id="", name="", description="", symbol="", href="",
+ chromosome="", MB="", GeneId=""):
+ Trait.__init__(self, id=id, name=name, href=href)
+ self.description = description
+ self.symbol = symbol
+ self.chromosome = chromosome
+ self.MB = MB
+ self.GeneId = GeneId
+
+ def populateDataId(self, cursor, freezeId):
+ """
+ Look up the data id for this trait given which
+ freeze it came from.
+ """
+ cursor.execute('''
+ SELECT
+ ProbeSetXRef.DataId
+ FROM
+ ProbeSetXRef
+ WHERE
+ ProbeSetId = %s AND
+ ProbeSetFreezeId = %s
+ ''' % (self.id, freezeId))
+
+ # we hope that there's only one record here
+ row = cursor.fetchone()
+ self.dataId = row[0]
+
+ #XZ, 03/03/2009: Xiaodong implemented this fuction
+ def populateStrainData(self, cursor):
+ cursor.execute('''
+ SELECT
+ ProbeSetData.StrainId,
+ ProbeSetData.value
+ FROM
+ ProbeSetData
+ WHERE
+ ProbeSetData.Id = %s''' % self.dataId)
+ for row in cursor.fetchall():
+ self.strainData[int(row[0])] = float(row[1])
+
+
+ def shortName(self):
+ """
+ An improved string method that uses the gene symbol where
+ we have it
+ """
+ if self.symbol != "":
+ return self.symbol
+ else:
+ return Trait.shortName(self)
+
+ def longName(self):
+ """
+ We use several bits of genetic information to give
+ useful information about this trait and where it is
+ """
+ if self.chromosome != "":
+ chrPart = " (%s on Chr %s @ %s Mb)" % (self.symbol,
+ self.chromosome,
+ self.MB)
+ else:
+ chrPart = ""
+
+ return "%s%s: %s" % (self.name, chrPart, self.description)
+
+ def header(self):
+ return ["Name", "Symbol", "Description",
+ "Chr", "Position (Mb)"]
+
+ def row(self):
+ if type(self.MB) is float:
+ MB = "%.2f" % self.MB
+ else:
+ MB = ""
+
+ return [self.name, self.symbol, self.description,
+ self.chromosome, MB]
+
+ def tableRow(self, beforeCols, afterCols, color):
+ """
+ tableRow: (arrayof String) -> (arrayof String) -> String
+ To generate a table row to represent this object, appending
+ the additional information in beforeCols and afterCols to the
+ beginning and end
+ """
+ thisRow = self.row()
+
+ # trim description
+ if len(thisRow[2]) > 20:
+ thisRow[2] = thisRow[2][:20] + "..."
+
+ # add NCBI info link
+ thisRow[1] = self.ncbiInfoLink()
+
+ return self.tableRowHelper(beforeCols, afterCols, color,
+ thisRow)
+
+
+ def ncbiInfoLink(self):
+ """
+ ncbiInfoLink :: String
+ To generate an NCBI info link for this trait. If we have a GeneId,
+ then we can go straight to the gene. If not, then we generate a search
+ link based on the gene symbol. If we have none of them, then we don't
+ generate a link at all.
+ """
+ if self.GeneId != "":
+ cmd = "cmd=Retrieve&dopt=Graphics&list_uids=%s" % self.GeneId
+ elif self.symbol != "":
+ cmd = "cmd=Search&term=%s" % self.symbol
+ else:
+ return ""
+
+ return '''
+
+ %s ''' % (cmd, self.symbol)
+
+
+# GenotypeTrait: a trait with data from the genotype
+class GenotypeTrait(Trait):
+ def __init__(self, id="", name="", href="", chromosome="", MB=""):
+ Trait.__init__(self, id=id, name=name, href=href)
+ self.chromosome = chromosome
+ self.MB = MB
+
+ def populateDataId(self, cursor, freezeId):
+ """
+ Look up the data id for this trait from the
+ genotype.
+ """
+ cursor.execute('''
+ SELECT
+ GenoXRef.DataId
+ FROM
+ GenoXRef
+ WHERE
+ GenoId = %s AND
+ GenoFreezeId = %s
+ ''' % (self.id, freezeId))
+
+ # we hope that there's only one record here
+ row = cursor.fetchone()
+ self.dataId = row[0]
+
+ #XZ, 03/03/2009: Xiaodong implemented this fuction
+ def populateStrainData(self, cursor):
+ cursor.execute('''
+ SELECT
+ GenoData.StrainId,
+ GenoData.value
+ FROM
+ GenoData
+ WHERE
+ GenoData.Id = %s''' % self.dataId)
+ for row in cursor.fetchall():
+ self.strainData[int(row[0])] = float(row[1])
+
+ def header(self):
+ return ["Locus", "Chr", "Position (Mb)"]
+
+ def row(self):
+ return [self.name, self.chromosome, "%.3f" % self.MB]
+
+ def tableRow(self, beforeCols, afterCols, color):
+ return self.tableRowHelper(beforeCols, afterCols, color, self.row())
+
+# PublishTrait: a trait with data from publications
+class PublishTrait(Trait):
+ def __init__(self, id="", name="", href="", authors="", title="",
+ phenotype="", year=""):
+ Trait.__init__(self, id=id, name=name, href=href)
+ self.authors = authors
+ self.title = title
+ self.phenotype = phenotype
+ self.year = year
+
+ def populateDataId(self, cursor, freezeId):
+ """
+ Look up the data id for this trait from the
+ published set. For the moment, we assume that there's
+ only one publish freeze.
+ """
+ cursor.execute('''
+ SELECT
+ PublishXRef.DataId
+ FROM
+ PublishXRef, PublishFreeze
+ WHERE
+ PublishFreeze.Id = %s AND
+ PublishFreeze.InbredSetId = PublishXRef.InbredSetId AND
+ PublishXRef.Id = %s
+ ''' % (freezeId, self.id))
+
+ # we hope that there's only one record here
+ row = cursor.fetchone()
+ self.dataId = row[0]
+
+ #XZ, 03/03/2009: Xiaodong implemented this fuction
+ def populateStrainData(self, cursor):
+ cursor.execute('''
+ SELECT
+ PublishData.StrainId,
+ PublishData.value
+ FROM
+ PublishData
+ WHERE
+ PublishData.Id = %s''' % self.dataId)
+ for row in cursor.fetchall():
+ self.strainData[int(row[0])] = float(row[1])
+
+
+ def longName(self):
+ """
+ A more intelligent string function that uses
+ information about the publication from which this trait came
+ """
+ return "%s: %s by %s" % (self.name, self.title, self.authors)
+
+ def header(self):
+ return ["Record", "Phenotype", "Authors", "Year", "URL"]
+
+ def row(self):
+ return [self.name,
+ self.phenotype,
+ self.authors,
+ str(self.year),
+ ""]
+
+ def tableRow(self, beforeCols, afterCols, color):
+ """
+ tableRow: (arrayof String) -> (arrayof String) -> String
+ To generate a table row to represent this object, appending
+ the additional information in beforeCols and afterCols to the
+ beginning and end
+ """
+ thisRow = self.row()
+
+ # for multiple authors, use "et. al" after first two
+ authors = thisRow[2].split(",")
+ if len(authors) > 2:
+ thisRow[2] = string.join(authors[:2], ",") + ", et al"
+
+ # clip phenotype to 20 chars
+ if len(thisRow[1]) > 20:
+ thisRow[1] = thisRow[1][:20] + "..."
+
+ # add Pub Med URL
+ thisRow[4] = 'Pub Med' % (CONFIG_pubMedLinkURL % self.href)
+
+ return self.tableRowHelper(beforeCols, afterCols, color,
+ thisRow)
+
+
+# TempTrait: a trait with data generate by user and stored in temp table
+class TempTrait(Trait):
+ def __init__(self, id="", name="", href="", description=""):
+ Trait.__init__(self, id=id, name=name, href=href)
+ self.description = description
+
+ def populateDataId(self, cursor, freeezeId):
+ """
+ Look up the data id for this trait from the Temp table, freezeId isn't used,
+ it just for fixing the inherit
+ """
+ cursor.execute('''
+ SELECT
+ DataId
+ FROM
+ Temp
+ WHERE
+ Id=%s
+ ''' % (self.id))
+
+ # we hope that there's only one record here
+ row = cursor.fetchone()
+ self.dataId = row[0]
+
+ #XZ, 03/03/2009: Xiaodong implemented this fuction
+ def populateStrainData(self, cursor):
+ cursor.execute('''
+ SELECT
+ TempData.StrainId,
+ TempData.value
+ FROM
+ TempData
+ WHERE
+ TempData.Id = %s''' % self.dataId)
+ for row in cursor.fetchall():
+ self.strainData[int(row[0])] = float(row[1])
+
+
+ def row(self):
+ return [self.id,
+ self.name,
+ self.description,
+ ""]
+
+
+ def longName(self):
+ """
+ For temp trait, the description always contents whole useful information
+ """
+ return self.description
+
+
+# queryGenotypeTraitByName : Cursor -> string -> GenotypeTrait
+def queryGenotypeTraitByName(cursor, speciesId, name):
+ qry = '''
+ SELECT
+ Geno.Id,
+ Geno.Name,
+ Geno.Chr,
+ Geno.Mb
+ FROM
+ Geno
+ WHERE
+ Geno.SpeciesId = %s and Geno.Name = "%s" ''' % (speciesId, name)
+
+ cursor.execute(qry)
+ row = cursor.fetchone()
+ return GenotypeTrait(id=row[0], name=row[1],
+ chromosome=row[2], MB=row[3])
+
+# queryPublishTraitByName : Cursor -> string -> PublishTrait
+def queryPublishTraitByName(cursor, freezeId, name):
+ qry = '''
+ SELECT
+ PublishXRef.Id,
+ Phenotype.Id,
+ Publication.Authors,
+ Publication.Title,
+ Publication.Year,
+ Publication.PubMed_ID
+ FROM
+ Publication, PublishXRef, Phenotype, PublishFreeze
+ WHERE
+ PublishFreeze.Id = %s AND
+ PublishFreeze.InbredSetId = PublishXRef.InbredSetId AND
+ PublishXRef.Id = %s AND
+ PublishXRef.PublicationId = Publication.Id AND
+ PublishXRef.PhenotypeId = Phenotype.Id
+ ''' % (freezeId, name)
+
+ cursor.execute(qry)
+ if cursor.rowcount == 0:
+ return None
+ else:
+ row = cursor.fetchone()
+
+ return PublishTrait(id=row[0], name='%s'%row[0],
+ authors=row[2], title=row[3],
+ year=row[4], href=row[5])
+
+
+def queryTempTraitByName(cursor, name):
+ name=name.strip()
+ qry = '''
+ SELECT
+ Temp.Id,
+ Temp.Name,
+ Temp.description
+ FROM
+ Temp
+ WHERE
+ Temp.Name= "%s"
+ ''' % (name)
+
+ cursor.execute(qry)
+ if cursor.rowcount == 0:
+ return None
+ else:
+ row = cursor.fetchone()
+ return TempTrait(id=row[0], name=row[1], description=row[2], href='')
+
+# queryPopulatedProbeSetTraits: Cursor -> Integer -> dictof Trait
+# to retrieve an entire probeset fully populated with data
+# this query can take 15+ sec the old way (22,000 traits * 35 strains = half
+# a million records)
+# so we ask for the data in bulk
+#
+# cursor should be SSCursor for MySQL so rows are stored on the server side
+# and tuples are used
+# we explicitly close the cursor here as well
+#XZ, 03/04/2009: It seems to me that this function is never be executed.
+#XZ: Although it can be called from multitrait.loadDatabase,
+#XZ: but the loadDatabase function will not be called
+#XZ: if the targetDatabaseType is probeset.
+#XZ: The probeset traits of target database are retrieved by execute
+#XZ: queryPopulatedProbeSetTraits2 from correlation.calcProbeSetPearsonMatrix
+def queryPopulatedProbeSetTraits(cursor, freezeId):
+ step1 = time.time()
+ traits = queryProbeSetTraits(cursor, freezeId)
+ traitDict = {}
+ for trait in traits:
+ traitDict[trait.id] = trait
+
+ step2 = time.time()
+ print
+ #XZ, 03/04/2009: Xiaodong changed Data to ProbeSetData
+ cursor.execute('''
+ SELECT
+ ProbeSetXRef.ProbeSetId,
+ ProbeSetData.StrainId,
+ ProbeSetData.value
+ FROM
+ ProbeSetXRef
+ Left Join ProbeSetData ON
+ ProbeSetXRef.DataId = ProbeSetData.Id
+ WHERE
+ ProbeSetXRef.ProbeSetFreezeId = %s
+ ''' % freezeId)
+
+ step3 = time.time()
+ totalrows = 0
+ somerows = cursor.fetchmany(1000)
+ while len(somerows) > 0:
+ totalrows += len(somerows)
+ for row in somerows:
+ # this line of code can execute more than one million times
+ traitDict[row[0]].strainData[int(row[1])] = row[2]
+ somerows = cursor.fetchmany(1000)
+
+ #cursor.close()
+ step4 = time.time()
+
+ time1 = step2 - step1
+ time2 = step3 - step2
+ time3 = step4 - step3
+ time4 = step4 - step1
+ #print "%f %f %f %f %d rows" % (round(time1, 2),
+ # round(time2, 2),
+ # round(time3, 2),
+ # round(time4, 2),
+ # totalrows)
+ #print "Fetched %d traits" % len(traits)
+ return traits
+
+
+# queryPopulatedProbeSetTraits2: Cursor -> Integer -> dictof Trait
+# to retrieve probeset fully populated whose ProbeSetId in a range
+# a special ProbeSetId with data
+# this query can take 15+ sec the old way (22,000 traits * 35 strains = half
+# a million records)
+# so we ask for the data in bulk
+#
+# cursor should be SSCursor for MySQL so rows are stored on the server side
+# and tuples are used
+# we explicitly close the cursor here as well
+def queryPopulatedProbeSetTraits2(cursor, freezeId, ProbeSetId1, ProbeSetId2):
+ step1 = time.time()
+ traits = queryProbeSetTraits2(cursor, freezeId, ProbeSetId1, ProbeSetId2)
+ traitDict = {}
+ for trait in traits:
+ traitDict[trait.id] = trait
+
+ step2 = time.time()
+ print
+ #XZ, 03/04/2009: Xiaodong changed Data to ProbeSetData
+ cursor.execute('''
+ SELECT
+ ProbeSetXRef.ProbeSetId,
+ ProbeSetData.StrainId,
+ ProbeSetData.value
+ FROM
+ ProbeSetXRef
+ Left Join ProbeSetData ON
+ ProbeSetXRef.DataId = ProbeSetData.Id
+ WHERE
+ ProbeSetXRef.ProbeSetFreezeId = %s AND
+ ProbeSetXRef.ProbeSetId >= %s AND
+ ProbeSetXRef.ProbeSetId <= %s
+ ''' % (freezeId, ProbeSetId1, ProbeSetId2))
+
+ step3 = time.time()
+ totalrows = 0
+ somerows = cursor.fetchmany(1000)
+ while len(somerows) > 0:
+ totalrows += len(somerows)
+ for row in somerows:
+ # this line of code can execute more than one million times
+ traitDict[row[0]].strainData[int(row[1])] = row[2]
+ somerows = cursor.fetchmany(1000)
+
+ #cursor.close()
+ step4 = time.time()
+
+ time1 = step2 - step1
+ time2 = step3 - step2
+ time3 = step4 - step3
+ time4 = step4 - step1
+ #print "%f %f %f %f %d rows" % (round(time1, 2),
+ # round(time2, 2),
+ # round(time3, 2),
+ # round(time4, 2),
+ # totalrows)
+ #print "Fetched %d traits" % len(traits)
+ return traits
+
+
+# def noneFilter : string or none -> string
+# to replace a possible None by an empty string
+def noneFilter(x):
+ if x is None:
+ return ""
+ else:
+ return x
+
+# queryProbeSetTraits: Cursor -> Integer -> dictof Trait
+def queryProbeSetTraits(cursor, freezeId):
+ """
+ To locate all of the traits in a particular probeset
+ """
+ qry = '''
+ SELECT
+ ProbeSet.Id,
+ ProbeSet.Name,
+ ProbeSet.description,
+ ProbeSet.symbol,
+ ProbeSet.Chr,
+ ProbeSet.Mb,
+ ProbeSet.GeneId,
+ ProbeSetXRef.DataId
+ FROM
+ ProbeSet,
+ ProbeSetXRef
+ WHERE
+ ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
+ ProbeSetXRef.ProbeSetFreezeId = %s
+ ORDER BY ProbeSet.Id
+ ''' % freezeId
+
+ cursor.execute(qry)
+ rows = cursor.fetchall()
+ traits = []
+
+ for row in rows:
+ row = map(noneFilter, row)
+ trait = ProbeSetTrait(id=row[0], name=row[1],
+ description=row[2],
+ chromosome=row[4],
+ MB=row[5],
+ symbol=row[3],
+ GeneId=row[6])
+ trait.dataId = row[7]
+ traits.append(trait)
+
+ return traits
+
+
+# queryProbeSetTraits2: Cursor -> Integer -> dictof Trait
+def queryProbeSetTraits2(cursor, freezeId, ProbeSetId1, ProbeSetId2):
+ """
+ To locate all of the traits in a particular probeset
+ """
+ qry = '''
+ SELECT
+ ProbeSet.Id,
+ ProbeSet.Name,
+ ProbeSet.description,
+ ProbeSet.symbol,
+ ProbeSet.Chr,
+ ProbeSet.Mb,
+ ProbeSet.GeneId,
+ ProbeSetXRef.DataId
+ FROM
+ ProbeSet,
+ ProbeSetXRef
+ WHERE
+ ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
+ ProbeSetXRef.ProbeSetFreezeId = %s AND
+ ProbeSet.Id >= %s AND
+ ProbeSet.Id <= %s
+ ORDER BY ProbeSet.Id
+ ''' % (freezeId, ProbeSetId1, ProbeSetId2)
+
+ cursor.execute(qry)
+ rows = cursor.fetchall()
+ traits = []
+
+ for row in rows:
+ row = map(noneFilter, row)
+ trait = ProbeSetTrait(id=row[0], name=row[1],
+ description=row[2],
+ chromosome=row[4],
+ MB=row[5],
+ symbol=row[3],
+ GeneId=row[6])
+ trait.dataId = row[7]
+ traits.append(trait)
+
+ return traits
+
+
+# queryPublishTraits : Cursor -> arrayof Trait
+def queryPublishTraits(cursor, freezeId):
+ """
+ To locate all published traits
+ """
+ qry = '''
+ SELECT
+ Publication.Id,
+ Publication.Name,
+ Publication.PhenoType,
+ Publication.Authors,
+ Publication.Title,
+ Publication.Year,
+ Publication.PubMed_ID,
+ PublishXRef.DataId
+ FROM
+ Publication,
+ PublishXRef
+ WHERE
+ PublishXRef.PublishFreezeId = %s AND
+ PublishXRef.PublishId = Publication.Id
+ ''' % freezeId
+
+ qry = '''
+ SELECT
+ Publication.Id,
+ PublishXRef.Id,
+ Phenotype.Pre_publication_description,
+ Phenotype.Post_publication_description,
+ Publication.Authors,
+ Publication.Title,
+ Publication.Year,
+ Publication.PubMed_ID,
+ PublishXRef.DataId
+ FROM
+ Publication, PublishXRef, Phenotype, PublishFreeze
+ WHERE
+ PublishFreeze.Id = %s AND
+ PublishFreeze.InbredSetId = PublishXRef.InbredSetId AND
+ PublishXRef.PublicationId = Publication.Id AND
+ PublishXRef.PhenotypeId = Phenotype.Id
+ ''' % freezeId
+ cursor.execute(qry)
+ rows = cursor.fetchall()
+ traits = []
+ for row in rows:
+ PhenotypeString = row[3]
+ if not row[7] and row[2]:
+ PhenotypeString = row[2]
+ trait = PublishTrait(id=row[0], name= '%s' %row[1],
+ phenotype=PhenotypeString,
+ authors=row[4],
+ title=row[5],
+ year=row[6],
+ href=row[7])
+ trait.dataId = row[8]
+ traits.append(trait)
+
+ return traits
+
+# queryGenotypeTraits : Cursor -> arrayof Trait
+def queryGenotypeTraits(cursor, freezeId):
+ """
+ To locate all traits in the genotype
+ """
+ qry = '''
+ SELECT
+ Geno.Id,
+ Geno.Name,
+ Geno.Chr,
+ GenoXRef.DataId,
+ Geno.Mb
+ FROM
+ Geno,
+ GenoXRef
+ WHERE
+ GenoXRef.GenoId = Geno.Id
+ AND GenoXRef.GenoFreezeId = %s
+ ''' % freezeId
+ cursor.execute(qry)
+ rows = cursor.fetchall()
+ traits = []
+
+ for row in rows:
+ trait = GenotypeTrait(id=row[0], name=row[1],
+ chromosome=row[2], MB=row[4])
+ trait.dataId = row[3]
+ traits.append(trait)
+
+ return traits
+
+# queryProbeSetTraitByName : Cursor -> string -> Trait
+# to find a particular trait given its name
+def queryProbeSetTraitByName(cursor, name):
+ qry = '''
+ SELECT
+ ProbeSet.Id,
+ ProbeSet.Name,
+ ProbeSet.description,
+ ProbeSet.symbol,
+ ProbeSet.Chr,
+ ProbeSet.Mb,
+ ProbeSet.GeneId
+ FROM
+ ProbeSet
+ WHERE
+ ProbeSet.Name = "%s"
+ ''' % name
+ #print qry
+ cursor.execute(qry)
+ row = cursor.fetchone()
+
+ # convert a MySQL NULL value to an empty string
+ # for gene symbol
+ if row[3] is None:
+ sym = ""
+ else:
+ sym = row[3]
+
+ return ProbeSetTrait(id=row[0], name=row[1], description=row[2],
+ symbol=sym, chromosome=row[4], MB=row[5],
+ GeneId=row[6])
+
+
+# queryTraits : Cursor -> string -> string -> arrayof Traits
+# to find all of the traits whose descriptions match a certain string in a
+# particular database
+def queryTraits(cursor, dbId, queryString):
+ # we do this in two steps:
+ # first we get the data id for the matching traits
+ qry = '''
+ SELECT
+ ProbeSet.Id,
+ ProbeSet.Name,
+ ProbeSet.description,
+ ProbeSetXRef.DataId
+ FROM
+ ProbeSet,
+ ProbeSetXRef
+ WHERE
+ ProbeSetXRef.ProbeSetFreezeId = %s AND
+ ProbeSet.Id = ProbeSetXRef.ProbeSetId AND
+ ProbeSet.description LIKE "%%%s%%"
+ ''' % (dbId, queryString)
+ # print qry
+ cursor.execute(qry)
+
+ if cursor.rowcount == 0:
+ print "No traits found"
+ return []
+ else:
+ print "%s traits found" % (cursor.rowcount)
+
+ # maybe fetchall is bad; we will see
+ traits = []
+ for row in cursor.fetchall():
+ myTrait = Trait(row[0], row[1], row[2])
+ myTrait.dataId = row[3]
+ traits.append(myTrait)
+
+ # second we pull all of the strain data for each trait
+ print "Retrieving individual trait data..."
+ for trait in traits:
+ trait.populateStrainData(cursor, trait.dataId)
+ print "%s (%s) -- %s" % (trait.name, trait.id, trait.description)
+
+ print "done"
+ return traits
+
+# queryProbeSetFreezes : Cursor -> arrayof String,String tuples
+# to return the short and long name for each ProbeSetFreeze
+# this function is designed specifically for building
+# a database selector
+def queryProbeSetFreezes(cursor):
+ cursor.execute("""
+ SELECT
+ ProbeSetFreeze.Name,
+ ProbeSetFreeze.FullName
+ FROM
+ ProbeSetFreeze
+ ORDER BY
+ ProbeSetFreeze.Name
+ """)
+
+ # for now, fetchall returns the data as a list of tuples
+ # which is what we want
+ return list(cursor.fetchall())
+
+# queryProbeSetFreezeIdName: Cursor -> String -> String, String
+# this function returns the
+# id and the long name of a probesetfreeze given its name
+# once again, it's designed specifically for building
+# the database selector
+def queryProbeSetFreezeIdName(cursor, name):
+ qry = ('''
+ SELECT
+ ProbeSetFreeze.Id,
+ ProbeSetFreeze.FullName
+ FROM
+ ProbeSetFreeze
+ WHERE
+ ProbeSetFreeze.Name = "%s"
+ ''' % name)
+ #print qry
+ cursor.execute(qry)
+
+ row = cursor.fetchone()
+ return row
+
+# queryProbeSetFreezeName: Cursor -> String -> String
+# to return the name of a probe set freeze given its id
+def queryProbeSetFreezeName(cursor, id):
+ cursor.execute('''
+ SELECT
+ ProbeSetFreeze.FullName
+ FROM
+ ProbeSetFreeze
+ WHERE
+ ProbeSetFreeze.Id = %s
+ ''' % id)
+
+ row = cursor.fetchone()
+ return row[0]
+
+# dbNameToTypeId : Cursor -> String -> (String, String)
+# to convert a database name to a (type, id) pair
+def dbNameToTypeId(cursor, name):
+ types = ["ProbeSet", "Geno", "Publish"]
+ for type_ in types:
+ count = cursor.execute('''
+ SELECT
+ %sFreeze.Id
+ FROM
+ %sFreeze
+ WHERE
+ Name = "%s"
+ ''' % (type_, type_, name))
+
+ if count != 0:
+ id = cursor.fetchone()[0]
+ return type_, id
+
+ return None, None
+
+# dbTypeIdToName : Cursor -> String -> String -> String
+# to convert a database (type,id) pair into a name
+def dbTypeIdToName(cursor, dbType, dbId):
+ cursor.execute('''
+ SELECT
+ %sFreeze.Name
+ FROM
+ %sFreeze
+ WHERE
+ Id = %s
+ ''' % (dbType, dbType, dbId))
+
+ row = cursor.fetchone()
+ return row[0]
+
+#XZ, July 21, 2010: I add this function
+def getSpeciesIdByDbTypeId (cursor, dbType, dbId):
+ cursor.execute('''
+ SELECT
+ SpeciesId
+ FROM
+ InbredSet, %sFreeze
+ WHERE
+ %sFreeze.Id = %s
+ and InbredSetId = InbredSet.Id
+ ''' % (dbType, dbType, dbId))
+
+ row = cursor.fetchone()
+ return row[0]
+
+
+# queryStrainCount : Cursor -> int
+# return the number of strains in the database
+def queryStrainCount(cursor):
+ cursor.execute('''
+ SELECT
+ Max(Strain.Id)
+ FROM
+ Strain
+ ''')
+ return (cursor.fetchone())[0]
diff --git a/web/webqtl/correlation/CorrelationPage.py b/web/webqtl/correlation/CorrelationPage.py
new file mode 100755
index 00000000..8ce669cb
--- /dev/null
+++ b/web/webqtl/correlation/CorrelationPage.py
@@ -0,0 +1,1958 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by NL 2011/02/11
+
+import string
+from math import *
+import cPickle
+import os
+import time
+import pyXLWriter as xl
+import pp
+import math
+
+from htmlgen import HTMLgen2 as HT
+import reaper
+
+from base import webqtlConfig
+from utility.THCell import THCell
+from utility.TDCell import TDCell
+from base.webqtlTrait import webqtlTrait
+from base.webqtlDataset import webqtlDataset
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from dbFunction import webqtlDatabaseFunction
+import utility.webqtlUtil #this is for parallel computing only.
+from correlation import correlationFunction
+
+
+class CorrelationPage(templatePage):
+
+ corrMinInformative = 4
+
+ def __init__(self, fd):
+
+ #XZ, 01/14/2009: This method is for parallel computing only.
+ #XZ: It is supposed to be called when "Genetic Correlation, Pearson's r" (method 1)
+ #XZ: or "Genetic Correlation, Spearman's rho" (method 2) is selected
+ def compute_corr( input_nnCorr, input_trait, input_list, computing_method):
+
+ allcorrelations = []
+
+ for line in input_list:
+ tokens = line.split('","')
+ tokens[-1] = tokens[-1][:-2] #remove the last "
+ tokens[0] = tokens[0][1:] #remove the first "
+
+ traitdataName = tokens[0]
+ database_trait = tokens[1:]
+
+ if computing_method == "1": #XZ: Pearson's r
+ corr,nOverlap = utility.webqtlUtil.calCorrelationText(input_trait, database_trait, input_nnCorr)
+ else: #XZ: Spearman's rho
+ corr,nOverlap = utility.webqtlUtil.calCorrelationRankText(input_trait, database_trait, input_nnCorr)
+ traitinfo = [traitdataName,corr,nOverlap]
+ allcorrelations.append(traitinfo)
+
+ return allcorrelations
+
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if not fd.genotype:
+ fd.readGenotype()
+
+ #XZ, 09/18/2008: get the information such as value, variance of the input strain names from the form.
+ if fd.allstrainlist:
+ mdpchoice = fd.formdata.getvalue('MDPChoice')
+ #XZ, in HTML source code, it is "BXD Only" or "BXH only", and so on
+ if mdpchoice == "1":
+ strainlist = fd.f1list + fd.strainlist
+ #XZ, in HTML source code, it is "MDP Only"
+ elif mdpchoice == "2":
+ strainlist = []
+ strainlist2 = fd.f1list + fd.strainlist
+ for strain in fd.allstrainlist:
+ if strain not in strainlist2:
+ strainlist.append(strain)
+ #So called MDP Panel
+ if strainlist:
+ strainlist = fd.f1list+fd.parlist+strainlist
+ #XZ, in HTML source code, it is "All Cases"
+ else:
+ strainlist = fd.allstrainlist
+ #XZ, 09/18/2008: put the trait data into dictionary fd.allTraitData
+ fd.readData(fd.allstrainlist)
+ else:
+ mdpchoice = None
+ strainlist = fd.strainlist
+ #XZ, 09/18/2008: put the trait data into dictionary fd.allTraitData
+ fd.readData()
+
+ #XZ, 3/16/2010: variable RISet must be pass by the form
+ RISet = fd.RISet
+ #XZ, 12/12/2008: get species infomation
+ species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet)
+
+ #XZ, 09/18/2008: get all information about the user selected database.
+ self.target_db_name = fd.formdata.getvalue('database')
+
+ try:
+ self.db = webqtlDataset(self.target_db_name, self.cursor)
+ except:
+ heading = "Correlation Table"
+ detail = ["The database you just requested has not been established yet."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, 09/18/2008: check if user has the authority to get access to the database.
+ if self.db.type == 'ProbeSet':
+ self.cursor.execute('SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM ProbeSetFreeze WHERE Name = "%s"' % self.target_db_name)
+ indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0]
+
+ if confidential == 1:
+ access_to_confidential_dataset = 0
+
+ #for the dataset that confidentiality is 1
+ #1. 'admin' and 'root' can see all of the dataset
+ #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table)
+ if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']:
+ access_to_confidential_dataset = 1
+ else:
+ AuthorisedUsersList=AuthorisedUsers.split(',')
+ if AuthorisedUsersList.__contains__(self.userName):
+ access_to_confidential_dataset = 1
+
+ if not access_to_confidential_dataset:
+ #Error, Confidential Database
+ heading = "Correlation Table"
+ detail = ["The %s database you selected is not open to the public at this time, please go back and select other database." % indFullName]
+ self.error(heading=heading,detail=detail,error="Confidential Database")
+ return
+
+ #XZ, 09/18/2008: filter out the strains that have no value.
+ _strains, _vals, _vars, N = fd.informativeStrains(strainlist)
+
+ N = len(_strains)
+
+ if N < self.corrMinInformative:
+ heading = "Correlation Table"
+ detail = ['Fewer than %d strain data were entered for %s data set. No calculation of correlation has been attempted.' % (self.corrMinInformative, RISet)]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, 09/28/2008: if user select "1", then display 1, 3 and 4.
+ #XZ, 09/28/2008: if user select "2", then display 2, 3 and 5.
+ #XZ, 09/28/2008: if user select "3", then display 1, 3 and 4.
+ #XZ, 09/28/2008: if user select "4", then display 1, 3 and 4.
+ #XZ, 09/28/2008: if user select "5", then display 2, 3 and 5.
+ methodDict = {"1":"Genetic Correlation (Pearson's r)","2":"Genetic Correlation (Spearman's rho)","3":"SGO Literature Correlation","4":"Tissue Correlation (Pearson's r)", "5":"Tissue Correlation (Spearman's rho)"}
+ self.method = fd.formdata.getvalue('method')
+ if self.method not in ("1","2","3","4","5"):
+ self.method = "1"
+
+ self.returnNumber = int(fd.formdata.getvalue('criteria'))
+
+ myTrait = fd.formdata.getvalue('fullname')
+ if myTrait:
+ myTrait = webqtlTrait(fullname=myTrait, cursor=self.cursor)
+ myTrait.retrieveInfo()
+
+ # We will not get Literature Correlations if there is no GeneId because there is nothing to look against
+ try:
+ input_trait_GeneId = int(fd.formdata.getvalue('GeneId'))
+ except:
+ input_trait_GeneId = None
+
+ # We will not get Tissue Correlations if there is no gene symbol because there is nothing to look against
+ try:
+ input_trait_symbol = myTrait.symbol
+ except:
+ input_trait_symbol = None
+
+
+ #XZ, 12/12/2008: if the species is rat or human, translate the geneid to mouse geneid
+ input_trait_mouse_geneid = self.translateToMouseGeneID(species, input_trait_GeneId)
+
+
+ #XZ: As of Nov/13/2010, this dataset is 'UTHSC Illumina V6.2 RankInv B6 D2 average CNS GI average (May 08)'
+ TissueProbeSetFreezeId = 1
+
+ #XZ, 09/22/2008: If we need search by GeneId,
+ #XZ, 09/22/2008: we have to check if this GeneId is in the literature or tissue correlation table.
+ #XZ, 10/15/2008: We also to check if the selected database is probeset type.
+ if self.method == "3" or self.method == "4" or self.method == "5":
+ if self.db.type != "ProbeSet":
+ self.error(heading="Wrong correlation type",detail="It is not possible to compute the %s between your trait and data in this %s database. Please try again after selecting another type of correlation." % (methodDict[self.method],self.db.name),error="Correlation Type Error")
+ return
+
+ """
+ if not input_trait_GeneId:
+ self.error(heading="No Associated GeneId",detail="This trait has no associated GeneId, so we are not able to show any literature or tissue related information.",error="No GeneId Error")
+ return
+ """
+
+ #XZ: We have checked geneid did exist
+
+ if self.method == "3":
+ if not input_trait_GeneId or not self.checkForLitInfo(input_trait_mouse_geneid):
+ self.error(heading="No Literature Info",detail="This gene does not have any associated Literature Information.",error="Literature Correlation Error")
+ return
+
+ if self.method == "4" or self.method == "5":
+ if not input_trait_symbol:
+ self.error(heading="No Tissue Correlation Information",detail="This gene does not have any associated Tissue Correlation Information.",error="Tissue Correlation Error")
+ return
+
+ if not self.checkSymbolForTissueCorr(TissueProbeSetFreezeId, myTrait.symbol):
+ self.error(heading="No Tissue Correlation Information",detail="This gene does not have any associated Tissue Correlation Information.",error="Tissue Correlation Error")
+ return
+
+############################################################################################################################################
+
+ allcorrelations = []
+ nnCorr = len(_vals)
+
+ #XZ: Use the fast method only for probeset dataset, and this dataset must have been created.
+ #XZ: Otherwise, use original method
+
+ useFastMethod = False
+
+ if self.db.type == "ProbeSet":
+
+ DatabaseFileName = self.getFileName( target_db_name=self.target_db_name )
+ DirectoryList = os.listdir(webqtlConfig.TEXTDIR) ### List of existing text files. Used to check if a text file already exists
+
+ if DatabaseFileName in DirectoryList:
+ useFastMethod = True
+
+ if useFastMethod:
+ if 1:
+ #try:
+ useLit = False
+ if self.method == "3":
+ litCorrs = self.fetchLitCorrelations(species=species, GeneId=input_trait_GeneId, db=self.db, returnNumber=self.returnNumber)
+ useLit = True
+
+ useTissueCorr = False
+ if self.method == "4" or self.method == "5":
+ tissueCorrs = self.fetchTissueCorrelations(db=self.db, primaryTraitSymbol=input_trait_symbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=self.method, returnNumber = self.returnNumber)
+ useTissueCorr = True
+
+ datasetFile = open(webqtlConfig.TEXTDIR+DatabaseFileName,'r')
+
+ #XZ, 01/08/2009: read the first line
+ line = datasetFile.readline()
+ dataset_strains = webqtlUtil.readLineCSV(line)[1:]
+
+ #XZ, 01/08/2009: This step is critical. It is necessary for this new method.
+ #XZ: The original function fetchAllDatabaseData uses all strains stored in variable _strains to
+ #XZ: retrieve the values of each strain from database in real time.
+ #XZ: The new method uses all strains stored in variable dataset_strains to create a new variable
+ #XZ: _newvals. _newvals has the same length as dataset_strains. The items in _newvals is in
+ #XZ: the same order of items in dataset_strains. The value of each item in _newvals is either
+ #XZ: the value of correspinding strain in _vals or 'None'.
+ _newvals = []
+ for item in dataset_strains:
+ if item in _strains:
+ _newvals.append(_vals[_strains.index(item)])
+ else:
+ _newvals.append('None')
+
+ nnCorr = len(_newvals)
+
+ #XZ, 01/14/2009: If literature corr or tissue corr is selected,
+ #XZ: there is no need to use parallel computing.
+ if useLit or useTissueCorr:
+ for line in datasetFile:
+ traitdata=webqtlUtil.readLineCSV(line)
+ traitdataName = traitdata[0]
+ traitvals = traitdata[1:]
+
+ if useLit:
+ if not litCorrs.has_key( traitdataName ):
+ continue
+
+ if useTissueCorr:
+ if not tissueCorrs.has_key( traitdataName ):
+ continue
+
+ if self.method == "3" or self.method == "4":
+ corr,nOverlap = webqtlUtil.calCorrelationText(traitvals,_newvals,nnCorr)
+ else:
+ corr,nOverlap = webqtlUtil.calCorrelationRankText(traitvals,_newvals,nnCorr)
+
+ traitinfo = [traitdataName,corr,nOverlap]
+
+ if useLit:
+ traitinfo.append(litCorrs[traitdataName])
+
+ if useTissueCorr:
+ tempCorr, tempPValue = tissueCorrs[traitdataName]
+ traitinfo.append(tempCorr)
+ traitinfo.append(tempPValue)
+
+ allcorrelations.append(traitinfo)
+ #XZ, 01/14/2009: If genetic corr is selected, use parallel computing
+ else:
+ input_line_list = datasetFile.readlines()
+ all_line_number = len(input_line_list)
+
+ step = 1000
+ job_number = math.ceil( float(all_line_number)/step )
+
+ job_input_lists = []
+
+ for job_index in range( int(job_number) ):
+ starti = job_index*step
+ endi = min((job_index+1)*step, all_line_number)
+
+ one_job_input_list = []
+
+ for i in range( starti, endi ):
+ one_job_input_list.append( input_line_list[i] )
+
+ job_input_lists.append( one_job_input_list )
+
+ ppservers = ()
+ # Creates jobserver with automatically detected number of workers
+ job_server = pp.Server(ppservers=ppservers)
+
+ jobs = []
+ results = []
+
+ for one_job_input_list in job_input_lists: #pay attention to modules from outside
+ jobs.append( job_server.submit(func=compute_corr, args=(nnCorr, _newvals, one_job_input_list, self.method), depfuncs=(), modules=("utility.webqtlUtil",)) )
+
+ for one_job in jobs:
+ one_result = one_job()
+ results.append( one_result )
+
+ for one_result in results:
+ for one_traitinfo in one_result:
+ allcorrelations.append( one_traitinfo )
+
+ datasetFile.close()
+ totalTraits = len(allcorrelations)
+ #except:
+ # useFastMethod = False
+ # self.error(heading="No computation method",detail="Something is wrong within the try except block in CorrelationPage python module.",error="Computation Error")
+ # return
+
+ #XZ, 01/08/2009: use the original method to retrieve from database and compute.
+ if not useFastMethod:
+
+ traitdatabase, dataStartPos = self.fetchAllDatabaseData(species=species, GeneId=input_trait_GeneId, GeneSymbol=input_trait_symbol, strains=_strains, db=self.db, method=self.method, returnNumber=self.returnNumber, tissueProbeSetFreezeId=TissueProbeSetFreezeId)
+
+ totalTraits = len(traitdatabase) #XZ, 09/18/2008: total trait number
+
+ for traitdata in traitdatabase:
+ traitdataName = traitdata[0]
+ traitvals = traitdata[dataStartPos:]
+ if self.method == "1" or self.method == "3" or self.method == "4":
+ corr,nOverlap = webqtlUtil.calCorrelation(traitvals,_vals,nnCorr)
+ else:
+ corr,nOverlap = webqtlUtil.calCorrelationRank(traitvals,_vals,nnCorr)
+
+ traitinfo = [traitdataName,corr,nOverlap]
+
+ #XZ, 09/28/2008: if user select '3', then fetchAllDatabaseData would give us LitCorr in the [1] position
+ #XZ, 09/28/2008: if user select '4' or '5', then fetchAllDatabaseData would give us Tissue Corr in the [1] position
+ #XZ, 09/28/2008: and Tissue Corr P Value in the [2] position
+ if input_trait_GeneId and self.db.type == "ProbeSet":
+ if self.method == "3":
+ traitinfo.append( traitdata[1] )
+ if self.method == "4" or self.method == "5":
+ traitinfo.append( traitdata[1] )
+ traitinfo.append( traitdata[2] )
+
+ allcorrelations.append(traitinfo)
+
+
+#############################################################
+
+ if self.method == "3" and input_trait_GeneId:
+ allcorrelations.sort(webqtlUtil.cmpLitCorr)
+ #XZ, 3/31/2010: Theoretically, we should create one function 'comTissueCorr'
+ #to compare each trait by their tissue corr p values.
+ #But because the tissue corr p values are generated by permutation test,
+ #the top ones always have p value 0. So comparing p values actually does nothing.
+ #In addition, for the tissue data in our database, the N is always the same.
+ #So it's safe to compare with tissue corr statistic value.
+ #That's the same as literature corr.
+ elif self.method in ["4","5"] and input_trait_GeneId:
+ allcorrelations.sort(webqtlUtil.cmpLitCorr)
+ else:
+ allcorrelations.sort(webqtlUtil.cmpCorr)
+
+
+ #XZ, 09/20/2008: we only need the top ones.
+ self.returnNumber = min(self.returnNumber,len(allcorrelations))
+ allcorrelations = allcorrelations[:self.returnNumber]
+
+ addLiteratureCorr = False
+ addTissueCorr = False
+
+ traitList = []
+ for item in allcorrelations:
+ thisTrait = webqtlTrait(db=self.db, name=item[0], cursor=self.cursor)
+ thisTrait.retrieveInfo( QTL='Yes' )
+
+ nOverlap = item[2]
+ corr = item[1]
+
+ #XZ: calculate corrPValue
+ if nOverlap < 3:
+ corrPValue = 1.0
+ else:
+ if abs(corr) >= 1.0:
+ corrPValue = 0.0
+ else:
+ ZValue = 0.5*log((1.0+corr)/(1.0-corr))
+ ZValue = ZValue*sqrt(nOverlap-3)
+ corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue)))
+
+ thisTrait.Name = item[0]
+ thisTrait.corr = corr
+ thisTrait.nOverlap = nOverlap
+ thisTrait.corrPValue = corrPValue
+ # NL, 07/19/2010
+ # js function changed, add a new parameter rankOrder for js function 'showTissueCorrPlot'
+ rankOrder = 0;
+ if self.method in ["2","5"]:
+ rankOrder = 1;
+ thisTrait.rankOrder =rankOrder
+
+ #XZ, 26/09/2008: Method is 4 or 5. Have fetched tissue corr, but no literature correlation yet.
+ if len(item) == 5:
+ thisTrait.tissueCorr = item[3]
+ thisTrait.tissuePValue = item[4]
+ addLiteratureCorr = True
+
+ #XZ, 26/09/2008: Method is 3, Have fetched literature corr, but no tissue corr yet.
+ elif len(item) == 4:
+ thisTrait.LCorr = item[3]
+ thisTrait.mouse_geneid = self.translateToMouseGeneID(species, thisTrait.geneid)
+ addTissueCorr = True
+
+ #XZ, 26/09/2008: Method is 1 or 2. Have NOT fetched literature corr and tissue corr yet.
+ # Phenotype data will not have geneid, and neither will some probes
+ # we need to handle this because we will get an attribute error
+ else:
+ if input_trait_mouse_geneid and self.db.type=="ProbeSet":
+ addLiteratureCorr = True
+ if input_trait_symbol and self.db.type=="ProbeSet":
+ addTissueCorr = True
+
+ traitList.append(thisTrait)
+
+ if addLiteratureCorr:
+ traitList = self.getLiteratureCorrelationByList(input_trait_mouse_geneid, species, traitList)
+ if addTissueCorr:
+ traitList = self.getTissueCorrelationByList( primaryTraitSymbol=input_trait_symbol, traitList=traitList,TissueProbeSetFreezeId =TissueProbeSetFreezeId, method=self.method)
+
+########################################################
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ mainfmName = webqtlUtil.genRandStr("fm_")
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name= mainfmName, submit=HT.Input(type='hidden'))
+ hddn = {'FormID':'showDatabase', 'ProbeSetID':'_','database':self.target_db_name, 'databaseFull':self.db.fullname, 'CellID':'_', 'RISet':RISet, 'identification':fd.identification}
+
+ if myTrait:
+ hddn['fullname']=fd.formdata.getvalue('fullname')
+ if mdpchoice:
+ hddn['MDPChoice']=mdpchoice
+
+
+ #XZ, 09/18/2008: pass the trait data to next page by hidden parameters.
+ webqtlUtil.exportData(hddn, fd.allTraitData)
+
+ if fd.incparentsf1:
+ hddn['incparentsf1']='ON'
+
+ if fd.allstrainlist:
+ hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ')
+
+
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ #XZ, 11/21/2008: add two parameters to form
+ form.append(HT.Input(name="X_geneSymbol", value="", type='hidden'))
+ form.append(HT.Input(name="Y_geneSymbol", value="", type='hidden'))
+
+ #XZ, 3/11/2010: add one parameter to record if the method is rank order.
+ form.append(HT.Input(name="rankOrder", value="%s" % rankOrder, type='hidden'))
+
+ form.append(HT.Input(name="TissueProbeSetFreezeId", value="%s" % TissueProbeSetFreezeId, type='hidden'))
+
+ ####################################
+ # generate the info on top of page #
+ ####################################
+
+ info = self.getTopInfo(myTrait=myTrait, method=self.method, db=self.db, target_db_name=self.target_db_name, returnNumber=self.returnNumber, methodDict=methodDict, totalTraits=totalTraits, identification=fd.identification )
+
+ ##############
+ # Excel file #
+ ##############
+ filename= webqtlUtil.genRandStr("Corr_")
+ xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button')
+ # Create a new Excel workbook
+ workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename))
+ headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white")
+
+ #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines.
+ worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, identification=fd.identification, db=self.db, returnNumber=self.returnNumber)
+
+ newrow = 7
+
+
+#####################################################################
+
+
+
+ mintmap = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'showIntMap');" % mainfmName)
+ mintmap_img = HT.Image("/images/multiple_interval_mapping1_final.jpg", name='mintmap', alt="Multiple Interval Mapping", title="Multiple Interval Mapping", style="border:none;")
+ mintmap.append(mintmap_img)
+ mcorr = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'compCorr');" % mainfmName)
+ mcorr_img = HT.Image("/images/compare_correlates2_final.jpg", alt="Compare Correlates", title="Compare Correlates", style="border:none;")
+ mcorr.append(mcorr_img)
+ cormatrix = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'corMatrix');" % mainfmName)
+ 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)
+ networkGraph = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'networkGraph');" % mainfmName)
+ networkGraph_img = HT.Image("/images/network_graph1_final.jpg", name='mintmap', alt="Network Graphs", title="Network Graphs", style="border:none;")
+ networkGraph.append(networkGraph_img)
+ heatmap = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'heatmap');" % mainfmName)
+ 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)
+ partialCorr = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'partialCorrInput');" % mainfmName)
+ partialCorr_img = HT.Image("/images/partial_correlation_final.jpg", name='partialCorr', alt="Partial Correlation", title="Partial Correlation", style="border:none;")
+ partialCorr.append(partialCorr_img)
+ addselect = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (RISet, mainfmName))
+ addselect_img = HT.Image("/images/add_collection1_final.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;")
+ addselect.append(addselect_img)
+ selectall = HT.Href(url="#redirect", onClick="checkAll(document.getElementsByName('%s')[0]);" % mainfmName)
+ selectall_img = HT.Image("/images/select_all2_final.jpg", name="selectall", alt="Select All", title="Select All", style="border:none;")
+ selectall.append(selectall_img)
+ selectinvert = HT.Href(url="#redirect", onClick = "checkInvert(document.getElementsByName('%s')[0]);" % mainfmName)
+ selectinvert_img = HT.Image("/images/invert_selection2_final.jpg", name="selectinvert", alt="Invert Selection", title="Invert Selection", style="border:none;")
+ selectinvert.append(selectinvert_img)
+ reset = HT.Href(url="#redirect", onClick="checkNone(document.getElementsByName('%s')[0]); return false;" % mainfmName)
+ reset_img = HT.Image("/images/select_none2_final.jpg", alt="Select None", title="Select None", style="border:none;")
+ reset.append(reset_img)
+ selecttraits = HT.Input(type='button' ,name='selecttraits',value='Select Traits', onClick="checkTraits(this.form);",Class="button")
+ selectgt = HT.Input(type='text' ,name='selectgt',value='-1.0', size=6,maxlength=10,onChange="checkNumeric(this,1.0,'-1.0','gthan','greater than filed')")
+ selectlt = HT.Input(type='text' ,name='selectlt',value='1.0', size=6,maxlength=10,onChange="checkNumeric(this,-1.0,'1.0','lthan','less than field')")
+ selectandor = HT.Select(name='selectandor')
+ selectandor.append(('AND','and'))
+ selectandor.append(('OR','or'))
+ selectandor.selected.append('AND')
+
+ pageTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="100%", border=0, align="Left")
+
+ containerTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="90%",border=0, align="Left")
+
+ optionsTable = HT.TableLite(cellSpacing=2, cellPadding=0,width="320", height="80", border=0, align="Left")
+ optionsTable.append(HT.TR(HT.TD(selectall), HT.TD(reset), HT.TD(selectinvert), HT.TD(addselect), align="left"))
+ optionsTable.append(HT.TR(HT.TD(" "*1,"Select"), HT.TD("Deselect"), HT.TD(" "*1,"Invert"), HT.TD(" "*3,"Add")))
+ containerTable.append(HT.TR(HT.TD(optionsTable)))
+
+ functionTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="480",height="80", border=0, align="Left")
+ functionRow = HT.TR(HT.TD(networkGraph, width="16.7%"), HT.TD(cormatrix, width="16.7%"), HT.TD(partialCorr, width="16.7%"), HT.TD(mcorr, width="16.7%"), HT.TD(mintmap, width="16.7%"), HT.TD(heatmap), align="left")
+ labelRow = HT.TR(HT.TD(" "*1,HT.Text("Graph")), HT.TD(" "*1,HT.Text("Matrix")), HT.TD(" "*1,HT.Text("Partial")), HT.TD(HT.Text("Compare")), HT.TD(HT.Text("QTL Map")), HT.TD(HT.Text(text="Heat Map")))
+ functionTable.append(functionRow, labelRow)
+ containerTable.append(HT.TR(HT.TD(functionTable), HT.BR()))
+
+ #more_options = HT.Image("/images/more_options1_final.jpg", name='more_options', alt="Expand Options", title="Expand Options", style="border:none;", Class="toggleShowHide")
+
+ #containerTable.append(HT.TR(HT.TD(more_options, HT.BR(), HT.BR())))
+
+ moreOptions = HT.Input(type='button',name='options',value='More Options', onClick="",Class="toggle")
+ fewerOptions = HT.Input(type='button',name='options',value='Fewer Options', onClick="",Class="toggle")
+
+ if (fd.formdata.getvalue('showHideOptions') == 'less'):
+ containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(fewerOptions, Class="toggleShowHide"))))
+ containerTable.append(HT.TR(HT.TD(" ")))
+ else:
+ containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(moreOptions, Class="toggleShowHide"))))
+ containerTable.append(HT.TR(HT.TD(" ")))
+
+ containerTable.append(HT.TR(HT.TD(HT.Span(selecttraits,' with r > ',selectgt, ' ',selectandor, ' r < ',selectlt,Class="bd1 cbddf fs11")), style="display:none;", Class="extra_options"))
+
+ chrMenu = HT.Input(type='hidden',name='chromosomes',value='all')
+
+ corrHeading = HT.Paragraph('Correlation Table', Class="title")
+
+
+ tblobj = {}
+
+ if self.db.type=="Geno":
+
+ containerTable.append(HT.TR(HT.TD(xlsUrl, height=40)))
+
+ pageTable.append(HT.TR(HT.TD(containerTable)))
+
+ tblobj['header'], worksheet = self.getTableHeaderForGeno( method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ sortby = self.getSortByValue( calculationMethod = self.method )
+
+ corrScript = HT.Script(language="Javascript")
+ corrScript.append("var corrArray = new Array();")
+
+ tblobj['body'], worksheet, corrScript = self.getTableBodyForGeno(traitList=traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript)
+
+ workbook.close()
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable")
+
+ pageTable.append(HT.TR(HT.TD(div)))
+
+ form.append(HT.Input(name='ShowStrains',type='hidden', value =1),
+ HT.Input(name='ShowLine',type='hidden', value =1),
+ HT.P(), HT.P(), pageTable)
+ TD_LR.append(corrHeading, info, form, HT.P())
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['js1'] = ''
+ self.dict['title'] = 'Correlation'
+
+ elif self.db.type=="Publish":
+
+ containerTable.append(HT.TR(HT.TD(xlsUrl, height=40)))
+
+ pageTable.append(HT.TR(HT.TD(containerTable)))
+
+ tblobj['header'], worksheet = self.getTableHeaderForPublish(method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ sortby = self.getSortByValue( calculationMethod = self.method )
+
+ corrScript = HT.Script(language="Javascript")
+ corrScript.append("var corrArray = new Array();")
+
+ tblobj['body'], worksheet, corrScript = self.getTableBodyForPublish(traitList=traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript, species=species)
+
+ workbook.close()
+
+ 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=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable")
+
+ pageTable.append(HT.TR(HT.TD(div)))
+
+ form.append(
+ HT.Input(name='ShowStrains',type='hidden', value =1),
+ HT.Input(name='ShowLine',type='hidden', value =1),
+ HT.P(), pageTable)
+ TD_LR.append(corrHeading, info, form, HT.P())
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['js1'] = ''
+ self.dict['title'] = 'Correlation'
+
+
+ elif self.db.type=="ProbeSet":
+
+ tblobj['header'], worksheet = self.getTableHeaderForProbeSet(method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ sortby = self.getSortByValue( calculationMethod = self.method )
+
+ corrScript = HT.Script(language="Javascript")
+ corrScript.append("var corrArray = new Array();")
+
+ tblobj['body'], worksheet, corrScript = self.getTableBodyForProbeSet(traitList=traitList, primaryTrait=myTrait, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript, species=species)
+
+ workbook.close()
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ #XZ: here is the table of traits
+ div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "1", hiddenColumns=["Gene ID","Homologene ID"]), corrScript, Id="sortable")
+
+
+ #XZ, 01/12/2009: create database menu for 'Add Correlation'
+ self.cursor.execute("""
+ select
+ ProbeSetFreeze.FullName, ProbeSetFreeze.Id, Tissue.name
+ from
+ ProbeSetFreeze, ProbeFreeze, ProbeSetFreeze as ps2, ProbeFreeze as p2, Tissue
+ where
+ ps2.Id = %d
+ and ps2.ProbeFreezeId = p2.Id
+ and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id
+ and (ProbeFreeze.InbredSetId = p2.InbredSetId or (ProbeFreeze.InbredSetId in (1, 3) and p2.InbredSetId in (1, 3)))
+ and p2.ChipId = ProbeFreeze.ChipId
+ and ps2.Id != ProbeSetFreeze.Id
+ and ProbeFreeze.TissueId = Tissue.Id
+ and ProbeSetFreeze.public > %d
+ order by
+ ProbeFreeze.TissueId, ProbeSetFreeze.CreateTime desc
+ """ % (self.db.id, webqtlConfig.PUBLICTHRESH))
+
+ results = self.cursor.fetchall()
+ dbCustomizer = HT.Select(results, name = "customizer")
+ databaseMenuSub = preTissue = ""
+ for item in results:
+ TName, TId, TTissue = item
+ if TTissue != preTissue:
+ if databaseMenuSub:
+ dbCustomizer.append(databaseMenuSub)
+ databaseMenuSub = HT.Optgroup(label = '%s mRNA ------' % TTissue)
+ preTissue = TTissue
+
+ databaseMenuSub.append(item[:2])
+ if databaseMenuSub:
+ dbCustomizer.append(databaseMenuSub)
+
+ #updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js
+ #variables: filename, strainIds and vals are required by getquerystring function
+ strainIds=self.getStrainIds(species=species, strains=_strains)
+ var1 = HT.Input(name="filename", value=filename, type='hidden')
+ var2 = HT.Input(name="strainIds", value=strainIds, type='hidden')
+ var3 = HT.Input(name="vals", value=_vals, type='hidden')
+ customizerButton = HT.Input(type="button", Class="button", value="Add Correlation", onClick = "xmlhttpPost('%smain.py?FormID=AJAX_table', 'sortable', (getquerystring(this.form)))" % webqtlConfig.CGIDIR)
+
+ containerTable.append(HT.TR(HT.TD(HT.Span(var1,var2,var3,customizerButton, "with", dbCustomizer, Class="bd1 cbddf fs11"), HT.BR(), HT.BR()), style="display:none;", Class="extra_options"))
+
+ #outside analysis part
+ GCATButton = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GCAT');" % mainfmName)
+ GCATButton_img = HT.Image("/images/GCAT_logo_final.jpg", name="GCAT", alt="GCAT", title="GCAT", style="border:none")
+ GCATButton.append(GCATButton_img)
+
+ ODE = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'ODE');" % mainfmName)
+ ODE_img = HT.Image("/images/ODE_logo_final.jpg", name="ode", alt="ODE", title="ODE", style="border:none")
+ ODE.append(ODE_img)
+
+ '''
+ #XZ, 07/07/2010: I comment out this block of code.
+ WebGestaltScript = HT.Script(language="Javascript")
+ WebGestaltScript.append("""
+setTimeout('openWebGestalt()', 2000);
+function openWebGestalt(){
+ var thisForm = document['WebGestalt'];
+ makeWebGestaltTree(thisForm, '%s', %d, 'edag_only.php');
+}
+ """ % (mainfmName, len(traitList)))
+ '''
+
+ self.cursor.execute('SELECT GeneChip.GO_tree_value FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % self.db.name)
+ result = self.cursor.fetchone()
+
+ if result:
+ GO_tree_value = result[0]
+
+ if GO_tree_value:
+
+ WebGestalt = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GOTree');" % mainfmName)
+ WebGestalt_img = HT.Image("/images/webgestalt_icon_final.jpg", name="webgestalt", alt="Gene Set Analysis Toolkit", title="Gene Set Analysis Toolkit", style="border:none")
+ WebGestalt.append(WebGestalt_img)
+
+ hddnWebGestalt = {
+ 'id_list':'',
+ 'correlation':'',
+ 'id_value':'',
+ 'llid_list':'',
+ 'id_type':GO_tree_value,
+ 'idtype':'',
+ 'species':'',
+ 'list':'',
+ 'client':''}
+
+ hddnWebGestalt['ref_type'] = hddnWebGestalt['id_type']
+ hddnWebGestalt['cat_type'] = 'GO'
+ hddnWebGestalt['significancelevel'] = 'Top10'
+
+ if species == 'rat':
+ hddnWebGestalt['org'] = 'Rattus norvegicus'
+ elif species == 'human':
+ hddnWebGestalt['org'] = 'Homo sapiens'
+ elif species == 'mouse':
+ hddnWebGestalt['org'] = 'Mus musculus'
+ else:
+ hddnWebGestalt['org'] = ''
+
+ for key in hddnWebGestalt.keys():
+ form.append(HT.Input(name=key, value=hddnWebGestalt[key], type='hidden'))
+
+
+ LinkOutTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="320",height="80", border=0, align="Left")
+
+ if not GO_tree_value:
+ LinkOutRow = HT.TR(HT.TD(GCATButton, width="50%"), HT.TD(ODE, width="50%"), align="left")
+ LinkOutLabels = HT.TR(HT.TD(" ", HT.Text("GCAT"), width="50%"), HT.TD(" ",HT.Text("ODE"), width="50%"), align="left")
+ else:
+ LinkOutRow = HT.TR(HT.TD(WebGestalt, width="25%"), HT.TD(GCATButton, width="25%"), HT.TD(ODE, width="25%"), align="left")
+ LinkOutLabels = HT.TR(HT.TD(HT.Text("Gene Set")), HT.TD(" "*2, HT.Text("GCAT")), HT.TD(" "*3, HT.Text("ODE")), style="display:none;", Class="extra_options")
+
+ LinkOutTable.append(LinkOutRow,LinkOutLabels)
+
+ containerTable.append(HT.TR(HT.TD(LinkOutTable), Class="extra_options", style="display:none;"))
+
+ containerTable.append(HT.TR(HT.TD(xlsUrl, HT.BR(), HT.BR())))
+
+ pageTable.append(HT.TR(HT.TD(containerTable)))
+
+ pageTable.append(HT.TR(HT.TD(div)))
+
+ if species == 'human':
+ heatmap = ""
+
+ form.append(HT.Input(name='ShowStrains',type='hidden', value =1),
+ HT.Input(name='ShowLine',type='hidden', value =1),
+ info, HT.BR(), pageTable, HT.BR())
+
+ TD_LR.append(corrHeading, form, HT.P())
+
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = 'Correlation'
+ # updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js
+ self.dict['js1'] = ''
+ self.dict['js2'] = 'onLoad="pageOffset()"'
+ self.dict['layer'] = self.generateWarningLayer()
+ else:
+ self.dict['body'] = ""
+
+
+#############################
+# #
+# CorrelationPage Functions #
+# #
+#############################
+
+
+ def getSortByValue(self, calculationMethod):
+
+ if calculationMethod == "1":
+ sortby = ("Sample p(r)", "up")
+ elif calculationMethod == "2":
+ sortby = ("Sample p(rho)", "up")
+ elif calculationMethod == "3": #XZ: literature correlation
+ sortby = ("Lit Corr","down")
+ elif calculationMethod == "4": #XZ: tissue correlation
+ sortby = ("Tissue r", "down")
+ elif calculationMethod == "5":
+ sortby = ("Tissue rho", "down")
+
+ return sortby
+
+
+
+ def generateWarningLayer(self):
+
+ layerString = """
+
+
+
+
+
+
+
+
+ Sort Table
+
+
+
+
+
+Resorting this table
+
+
+
+
+
+
+
+
+
+
+ """
+
+ return layerString
+
+
+ #XZ, 01/07/2009: In HTML code, the variable 'database' corresponds to the column 'Name' in database table.
+ def getFileName(self, target_db_name): ### dcrowell August 2008
+ """Returns the name of the reference database file with which correlations are calculated.
+ Takes argument cursor which is a cursor object of any instance of a subclass of templatePage
+ Used by correlationPage"""
+
+ query = 'SELECT Id, FullName FROM ProbeSetFreeze WHERE Name = "%s"' % target_db_name
+ self.cursor.execute(query)
+ result = self.cursor.fetchone()
+ Id = result[0]
+ FullName = result[1]
+ FullName = FullName.replace(' ','_')
+ FullName = FullName.replace('/','_')
+
+ FileName = 'ProbeSetFreezeId_' + str(Id) + '_FullName_' + FullName + '.txt'
+
+ return FileName
+
+
+ #XZ, 01/29/2009: I modified this function.
+ #XZ: Note that the type of StrainIds must be number, not string.
+ def getStrainIds(self, species=None, strains=[]):
+ StrainIds = []
+ for item in strains:
+ self.cursor.execute('''SELECT Strain.Id FROM Strain, Species WHERE
+ Strain.Name="%s" and Strain.SpeciesId=Species.Id and Species.name = "%s" ''' % (item, species))
+ Id = self.cursor.fetchone()[0]
+ StrainIds.append(Id)
+
+ return StrainIds
+
+
+ #XZ, 12/12/2008: if the species is rat or human, translate the geneid to mouse geneid
+ #XZ, 12/12/2008: if the input geneid is 'None', return 0
+ #XZ, 12/12/2008: if the input geneid has no corresponding mouse geneid, return 0
+ def translateToMouseGeneID (self, species, geneid):
+ mouse_geneid = 0;
+
+ #if input geneid is None, return 0.
+ if not geneid:
+ return mouse_geneid
+
+ if species == 'mouse':
+ mouse_geneid = geneid
+ elif species == 'rat':
+ self.cursor.execute( "SELECT mouse FROM GeneIDXRef WHERE rat=%d" % int(geneid) )
+ record = self.cursor.fetchone()
+ if record:
+ mouse_geneid = record[0]
+ elif species == 'human':
+ self.cursor.execute( "SELECT mouse FROM GeneIDXRef WHERE human=%d" % int(geneid) )
+ record = self.cursor.fetchone()
+ if record:
+ mouse_geneid = record[0]
+
+ return mouse_geneid
+
+
+ #XZ, 12/16/2008: the input geneid is of mouse type
+ def checkForLitInfo(self,geneId):
+ q = 'SELECT 1 FROM LCorrRamin3 WHERE GeneId1=%s LIMIT 1' % geneId
+ self.cursor.execute(q)
+ try:
+ x = self.cursor.fetchone()
+ if x: return True
+ else: raise
+ except: return False
+
+
+ #XZ, 12/16/2008: the input geneid is of mouse type
+ def checkSymbolForTissueCorr(self, tissueProbeSetFreezeId=0, symbol=""):
+ q = "SELECT 1 FROM TissueProbeSetXRef WHERE TissueProbeSetFreezeId=%s and Symbol='%s' LIMIT 1" % (tissueProbeSetFreezeId,symbol)
+ self.cursor.execute(q)
+ try:
+ x = self.cursor.fetchone()
+ if x: return True
+ else: raise
+ except: return False
+
+
+
+ def fetchAllDatabaseData(self, species, GeneId, GeneSymbol, strains, db, method, returnNumber, tissueProbeSetFreezeId):
+
+ StrainIds = []
+ for item in strains:
+ self.cursor.execute('''SELECT Strain.Id FROM Strain, Species WHERE Strain.Name="%s" and Strain.SpeciesId=Species.Id and Species.name = "%s" ''' % (item, species))
+ Id = self.cursor.fetchone()[0]
+ StrainIds.append('%d' % Id)
+
+ # break it into smaller chunks so we don't overload the MySql server
+ nnn = len(StrainIds) / 25
+ if len(StrainIds) % 25:
+ nnn += 1
+ oridata = []
+
+ #XZ, 09/24/2008: build one temporary table that only contains the records associated with the input GeneId
+ tempTable = None
+ if GeneId and db.type == "ProbeSet":
+ if method == "3":
+ tempTable = self.getTempLiteratureTable(species=species, input_species_geneid=GeneId, returnNumber=returnNumber)
+
+ if method == "4" or method == "5":
+ tempTable = self.getTempTissueCorrTable(primaryTraitSymbol=GeneSymbol, TissueProbeSetFreezeId=tissueProbeSetFreezeId, method=method, returnNumber=returnNumber)
+
+ for step in range(nnn):
+ temp = []
+ StrainIdstep = StrainIds[step*25:min(len(StrainIds), (step+1)*25)]
+ for item in StrainIdstep: temp.append('T%s.value' % item)
+
+ if db.type == "Publish":
+ query = "SELECT PublishXRef.Id, "
+ dataStartPos = 1
+ query += string.join(temp,', ')
+ query += ' FROM (PublishXRef, PublishFreeze)'
+ #XZ, 03/04/2009: Xiaodong changed Data to PublishData
+ for item in StrainIdstep:
+ query += 'left join PublishData as T%s on T%s.Id = PublishXRef.DataId and T%s.StrainId=%s\n' %(item,item,item,item)
+ query += "WHERE PublishXRef.InbredSetId = PublishFreeze.InbredSetId and PublishFreeze.Name = '%s'" % (db.name, )
+ #XZ, 09/20/2008: extract literature correlation value together with gene expression values.
+ #XZ, 09/20/2008: notice the difference between the code in next block.
+ elif tempTable:
+ # we can get a little performance out of selecting our LitCorr here
+ # but also we need to do this because we are unconcerned with probes that have no geneId associated with them
+ # as we would not have litCorr data.
+
+ if method == "3":
+ query = "SELECT %s.Name, %s.value," % (db.type,tempTable)
+ dataStartPos = 2
+ if method == "4" or method == "5":
+ query = "SELECT %s.Name, %s.Correlation, %s.PValue," % (db.type,tempTable, tempTable)
+ dataStartPos = 3
+
+ query += string.join(temp,', ')
+ query += ' FROM (%s, %sXRef, %sFreeze)' % (db.type, db.type, db.type)
+ if method == "3":
+ query += ' LEFT JOIN %s ON %s.GeneId2=ProbeSet.GeneId ' % (tempTable,tempTable)
+ if method == "4" or method == "5":
+ query += ' LEFT JOIN %s ON %s.Symbol=ProbeSet.Symbol ' % (tempTable,tempTable)
+ #XZ, 03/04/2009: Xiaodong changed Data to %sData and changed parameters from %(item,item, db.type,item,item) to %(db.type, item,item, db.type,item,item)
+ for item in StrainIdstep:
+ query += 'left join %sData as T%s on T%s.Id = %sXRef.DataId and T%s.StrainId=%s\n' %(db.type, item,item, db.type,item,item)
+
+ if method == "3":
+ query += "WHERE ProbeSet.GeneId IS NOT NULL AND %s.value IS NOT NULL AND %sXRef.%sFreezeId = %sFreeze.Id and %sFreeze.Name = '%s' and %s.Id = %sXRef.%sId order by %s.Id" % (tempTable,db.type, db.type, db.type, db.type, db.name, db.type, db.type, db.type, db.type)
+ if method == "4" or method == "5":
+ query += "WHERE ProbeSet.Symbol IS NOT NULL AND %s.Correlation IS NOT NULL AND %sXRef.%sFreezeId = %sFreeze.Id and %sFreeze.Name = '%s' and %s.Id = %sXRef.%sId order by %s.Id" % (tempTable,db.type, db.type, db.type, db.type, db.name, db.type, db.type, db.type, db.type)
+ else:
+ query = "SELECT %s.Name," % db.type
+ dataStartPos = 1
+ query += string.join(temp,', ')
+ query += ' FROM (%s, %sXRef, %sFreeze)' % (db.type, db.type, db.type)
+ #XZ, 03/04/2009: Xiaodong changed Data to %sData and changed parameters from %(item,item, db.type,item,item) to %(db.type, item,item, db.type,item,item)
+ for item in StrainIdstep:
+ query += 'left join %sData as T%s on T%s.Id = %sXRef.DataId and T%s.StrainId=%s\n' %(db.type, item,item, db.type,item,item)
+ query += "WHERE %sXRef.%sFreezeId = %sFreeze.Id and %sFreeze.Name = '%s' and %s.Id = %sXRef.%sId order by %s.Id" % (db.type, db.type, db.type, db.type, db.name, db.type, db.type, db.type, db.type)
+
+ self.cursor.execute(query)
+ results = self.cursor.fetchall()
+ oridata.append(results)
+
+ datasize = len(oridata[0])
+ traitdatabase = []
+ # put all of the seperate data together into a huge list of lists
+ for j in range(datasize):
+ traitdata = list(oridata[0][j])
+ for i in range(1,nnn):
+ traitdata += list(oridata[i][j][dataStartPos:])
+ traitdatabase.append(traitdata)
+
+ if tempTable:
+ self.cursor.execute( 'DROP TEMPORARY TABLE %s' % tempTable )
+
+ return traitdatabase, dataStartPos
+
+
+ # XZ, 09/20/2008: This function creates TEMPORARY TABLE tmpTableName_2 and return its name.
+ # XZ, 09/20/2008: It stores top literature correlation values associated with the input geneId.
+ # XZ, 09/20/2008: Attention: In each row, the input geneId is always in column GeneId1.
+ #XZ, 12/16/2008: the input geneid can be of mouse, rat or human type
+ def getTempLiteratureTable(self, species, input_species_geneid, returnNumber):
+ # according to mysql the TEMPORARY TABLE name should not have to be unique because
+ # it is only available to the current connection. This program will be invoked via command line, but if it
+ # were to be invoked over mod_python this could cuase problems. mod_python will keep the connection alive
+ # in its executing threads ( i think) so there is a potential for the table not being dropped between users.
+ #XZ, 01/29/2009: To prevent the potential risk, I generate random table names and drop the tables after use them.
+
+
+ # the 'input_species_geneid' could be rat or human geneid, need to translate it to mouse geneid
+ translated_mouse_geneid = self.translateToMouseGeneID (species, input_species_geneid)
+
+ tmpTableName_1 = webqtlUtil.genRandStr(prefix="LITERATURE")
+
+ q1 = 'CREATE TEMPORARY TABLE %s (GeneId1 int(12) unsigned, GeneId2 int(12) unsigned PRIMARY KEY, value double)' % tmpTableName_1
+ q2 = 'INSERT INTO %s (GeneId1, GeneId2, value) SELECT GeneId1,GeneId2,value FROM LCorrRamin3 WHERE GeneId1=%s' % (tmpTableName_1, translated_mouse_geneid)
+ q3 = 'INSERT INTO %s (GeneId1, GeneId2, value) SELECT GeneId2,GeneId1,value FROM LCorrRamin3 WHERE GeneId2=%s AND GeneId1!=%s' % (tmpTableName_1, translated_mouse_geneid,translated_mouse_geneid)
+ for x in [q1,q2,q3]: self.cursor.execute(x)
+
+ #XZ, 09/23/2008: Just use the top records insteard of using all records
+ tmpTableName_2 = webqtlUtil.genRandStr(prefix="TOPLITERATURE")
+
+ q1 = 'CREATE TEMPORARY TABLE %s (GeneId1 int(12) unsigned, GeneId2 int(12) unsigned PRIMARY KEY, value double)' % tmpTableName_2
+ self.cursor.execute(q1)
+ q2 = 'SELECT GeneId1, GeneId2, value FROM %s ORDER BY value DESC' % tmpTableName_1
+ self.cursor.execute(q2)
+ result = self.cursor.fetchall()
+
+ counter = 0 #this is to count how many records being inserted into table
+ for one_row in result:
+ mouse_geneid1, mouse_geneid2, lit_corr_alue = one_row
+
+ #mouse_geneid1 has been tested before, now should test if mouse_geneid2 has corresponding geneid in other species
+ translated_species_geneid = 0
+ if species == 'mouse':
+ translated_species_geneid = mouse_geneid2
+ elif species == 'rat':
+ self.cursor.execute( "SELECT rat FROM GeneIDXRef WHERE mouse=%d" % int(mouse_geneid2) )
+ record = self.cursor.fetchone()
+ if record:
+ translated_species_geneid = record[0]
+ elif species == 'human':
+ self.cursor.execute( "SELECT human FROM GeneIDXRef WHERE mouse=%d" % int(mouse_geneid2) )
+ record = self.cursor.fetchone()
+ if record:
+ translated_species_geneid = record[0]
+
+ if translated_species_geneid:
+ self.cursor.execute( 'INSERT INTO %s (GeneId1, GeneId2, value) VALUES (%d,%d,%f)' % (tmpTableName_2, int(input_species_geneid),int(translated_species_geneid), float(lit_corr_alue)) )
+ counter = counter + 1
+
+ #pay attention to the number
+ if (counter > 2*returnNumber):
+ break
+
+ self.cursor.execute('DROP TEMPORARY TABLE %s' % tmpTableName_1)
+
+ return tmpTableName_2
+
+
+
+ #XZ, 09/23/2008: In tissue correlation tables, there is no record of GeneId1 == GeneId2
+ #XZ, 09/24/2008: Note that the correlation value can be negative.
+ def getTempTissueCorrTable(self, primaryTraitSymbol="", TissueProbeSetFreezeId=0, method="", returnNumber=0):
+
+ def cmpTissCorrAbsoluteValue(A, B):
+ try:
+ if abs(A[1]) < abs(B[1]): return 1
+ elif abs(A[1]) == abs(B[1]):
+ return 0
+ else: return -1
+ except:
+ return 0
+
+ symbolCorrDict, symbolPvalueDict = self.calculateCorrOfAllTissueTrait(primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=method)
+
+ symbolCorrList = symbolCorrDict.items()
+
+ symbolCorrList.sort(cmpTissCorrAbsoluteValue)
+ symbolCorrList = symbolCorrList[0 : 2*returnNumber]
+
+ tmpTableName = webqtlUtil.genRandStr(prefix="TOPTISSUE")
+
+ q1 = 'CREATE TEMPORARY TABLE %s (Symbol varchar(100) PRIMARY KEY, Correlation float, PValue float)' % tmpTableName
+ self.cursor.execute(q1)
+
+ for one_pair in symbolCorrList:
+ one_symbol = one_pair[0]
+ one_corr = one_pair[1]
+ one_p_value = symbolPvalueDict[one_symbol]
+
+ self.cursor.execute( "INSERT INTO %s (Symbol, Correlation, PValue) VALUES ('%s',%f,%f)" % (tmpTableName, one_symbol, float(one_corr), float(one_p_value)) )
+
+ return tmpTableName
+
+
+ #XZ, 01/09/2009: This function was created by David Crowell. Xiaodong cleaned up and modified it.
+ def fetchLitCorrelations(self, species, GeneId, db, returnNumber): ### Used to generate Lit Correlations when calculations are done from text file. dcrowell August 2008
+ """Uses getTempLiteratureTable to generate table of literatire correlations. This function then gathers that data and
+ pairs it with the TraitID string. Takes as its arguments a formdata instance, and a database instance.
+ Returns a dictionary of 'TraitID':'LitCorr' for the requested correlation"""
+
+ tempTable = self.getTempLiteratureTable(species=species, input_species_geneid=GeneId, returnNumber=returnNumber)
+
+ query = "SELECT %s.Name, %s.value" % (db.type,tempTable)
+ query += ' FROM (%s, %sXRef, %sFreeze)' % (db.type, db.type, db.type)
+ query += ' LEFT JOIN %s ON %s.GeneId2=ProbeSet.GeneId ' % (tempTable,tempTable)
+ query += "WHERE ProbeSet.GeneId IS NOT NULL AND %s.value IS NOT NULL AND %sXRef.%sFreezeId = %sFreeze.Id and %sFreeze.Name = '%s' and %s.Id = %sXRef.%sId order by %s.Id" % (tempTable, db.type, db.type, db.type, db.type, db.name, db.type, db.type, db.type, db.type)
+
+ self.cursor.execute(query)
+ results = self.cursor.fetchall()
+
+ litCorrDict = {}
+
+ for entry in results:
+ traitName,litcorr = entry
+ litCorrDict[traitName] = litcorr
+
+ self.cursor.execute('DROP TEMPORARY TABLE %s' % tempTable)
+
+ return litCorrDict
+
+
+
+ #XZ, 01/09/2009: Xiaodong created this function.
+ def fetchTissueCorrelations(self, db, primaryTraitSymbol="", TissueProbeSetFreezeId=0, method="", returnNumber = 0):
+ """Uses getTempTissueCorrTable to generate table of tissue correlations. This function then gathers that data and
+ pairs it with the TraitID string. Takes as its arguments a formdata instance, and a database instance.
+ Returns a dictionary of 'TraitID':(tissueCorr, tissuePValue) for the requested correlation"""
+
+
+ tempTable = self.getTempTissueCorrTable(primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=method, returnNumber=returnNumber)
+
+ query = "SELECT ProbeSet.Name, %s.Correlation, %s.PValue" % (tempTable, tempTable)
+ query += ' FROM (ProbeSet, ProbeSetXRef, ProbeSetFreeze)'
+ query += ' LEFT JOIN %s ON %s.Symbol=ProbeSet.Symbol ' % (tempTable,tempTable)
+ query += "WHERE ProbeSetFreeze.Name = '%s' and ProbeSetFreeze.Id=ProbeSetXRef.ProbeSetFreezeId and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSet.Symbol IS NOT NULL AND %s.Correlation IS NOT NULL" % (db.name, tempTable)
+
+ self.cursor.execute(query)
+ results = self.cursor.fetchall()
+
+ tissueCorrDict = {}
+
+ for entry in results:
+ traitName, tissueCorr, tissuePValue = entry
+ tissueCorrDict[traitName] = (tissueCorr, tissuePValue)
+
+ self.cursor.execute('DROP TEMPORARY TABLE %s' % tempTable)
+
+ return tissueCorrDict
+
+
+
+ #XZ, 01/13/2008
+ def getLiteratureCorrelationByList(self, input_trait_mouse_geneid=None, species=None, traitList=None):
+
+ tmpTableName = webqtlUtil.genRandStr(prefix="LITERATURE")
+
+ q1 = 'CREATE TEMPORARY TABLE %s (GeneId1 int(12) unsigned, GeneId2 int(12) unsigned PRIMARY KEY, value double)' % tmpTableName
+ q2 = 'INSERT INTO %s (GeneId1, GeneId2, value) SELECT GeneId1,GeneId2,value FROM LCorrRamin3 WHERE GeneId1=%s' % (tmpTableName, input_trait_mouse_geneid)
+ q3 = 'INSERT INTO %s (GeneId1, GeneId2, value) SELECT GeneId2,GeneId1,value FROM LCorrRamin3 WHERE GeneId2=%s AND GeneId1!=%s' % (tmpTableName, input_trait_mouse_geneid, input_trait_mouse_geneid)
+
+ for x in [q1,q2,q3]:
+ self.cursor.execute(x)
+
+ for thisTrait in traitList:
+ try:
+ if thisTrait.geneid:
+ thisTrait.mouse_geneid = self.translateToMouseGeneID(species, thisTrait.geneid)
+ else:
+ thisTrait.mouse_geneid = 0
+ except:
+ thisTrait.mouse_geneid = 0
+
+ if thisTrait.mouse_geneid and str(thisTrait.mouse_geneid).find(";") == -1:
+ try:
+ self.cursor.execute("SELECT value FROM %s WHERE GeneId2 = %s" % (tmpTableName, thisTrait.mouse_geneid))
+ result = self.cursor.fetchone()
+ if result:
+ thisTrait.LCorr = result[0]
+ else:
+ thisTrait.LCorr = None
+ except:
+ thisTrait.LCorr = None
+ else:
+ thisTrait.LCorr = None
+
+ self.cursor.execute("DROP TEMPORARY TABLE %s" % tmpTableName)
+
+ return traitList
+
+
+
+ def calculateCorrOfAllTissueTrait(self, primaryTraitSymbol=None, TissueProbeSetFreezeId=None, method=None):
+
+ symbolCorrDict = {}
+ symbolPvalueDict = {}
+
+ primaryTraitSymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[primaryTraitSymbol], TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+ primaryTraitValue = primaryTraitSymbolValueDict.values()[0]
+
+ SymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[], TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+
+ if method in ["2","5"]:
+ symbolCorrDict, symbolPvalueDict = correlationFunction.batchCalTissueCorr(primaryTraitValue,SymbolValueDict,method='spearman')
+ else:
+ symbolCorrDict, symbolPvalueDict = correlationFunction.batchCalTissueCorr(primaryTraitValue,SymbolValueDict)
+
+
+ return (symbolCorrDict, symbolPvalueDict)
+
+
+
+ #XZ, 10/13/2010
+ def getTissueCorrelationByList(self, primaryTraitSymbol=None, traitList=None, TissueProbeSetFreezeId=None, method=None):
+
+ primaryTraitSymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[primaryTraitSymbol], TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+
+ if primaryTraitSymbol.lower() in primaryTraitSymbolValueDict:
+ primaryTraitValue = primaryTraitSymbolValueDict[primaryTraitSymbol.lower()]
+
+ geneSymbolList = []
+
+ for thisTrait in traitList:
+ if hasattr(thisTrait, 'symbol'):
+ geneSymbolList.append(thisTrait.symbol)
+
+ SymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=geneSymbolList, TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+
+ for thisTrait in traitList:
+ if hasattr(thisTrait, 'symbol') and thisTrait.symbol and thisTrait.symbol.lower() in SymbolValueDict:
+ oneTraitValue = SymbolValueDict[thisTrait.symbol.lower()]
+ if method in ["2","5"]:
+ result = correlationFunction.calZeroOrderCorrForTiss( primaryTraitValue, oneTraitValue, method='spearman' )
+ else:
+ result = correlationFunction.calZeroOrderCorrForTiss( primaryTraitValue, oneTraitValue)
+ thisTrait.tissueCorr = result[0]
+ thisTrait.tissuePValue = result[2]
+ else:
+ thisTrait.tissueCorr = None
+ thisTrait.tissuePValue = None
+ else:
+ for thisTrait in traitList:
+ thisTrait.tissueCorr = None
+ thisTrait.tissuePValue = None
+
+ return traitList
+
+
+ def getTopInfo(self, myTrait=None, method=None, db=None, target_db_name=None, returnNumber=None, methodDict=None, totalTraits=None, identification=None ):
+
+ if myTrait:
+ if method in ["1","2"]: #genetic correlation
+ info = HT.Paragraph("Values of Record %s in the " % myTrait.getGivenName(), HT.Href(text=myTrait.db.fullname,url=webqtlConfig.INFOPAGEHREF % myTrait.db.name,target="_blank", Class="fwn"),
+ " database were compared to all %d records in the " % totalTraits, HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank", Class="fwn"),
+ ' database. The top %d correlations ranked by the %s are displayed.' % (returnNumber,methodDict[method]),
+ ' You can resort this list using the small arrowheads in the top row.')
+ else:
+ #myTrait.retrieveInfo()#need to know geneid and symbol
+ if method == "3":#literature correlation
+ searchDBName = "Literature Correlation"
+ searchDBLink = "/correlationAnnotation.html#literatureCorr"
+ else: #tissue correlation
+ searchDBName = "Tissue Correlation"
+ searchDBLink = "/correlationAnnotation.html#tissueCorr"
+ info = HT.Paragraph("Your input record %s in the " % myTrait.getGivenName(), HT.Href(text=myTrait.db.fullname,url=webqtlConfig.INFOPAGEHREF % myTrait.db.name,target="_blank", Class="fwn"),
+ " database corresponds to ",
+ HT.Href(text='gene Id %s, and gene symbol %s' % (myTrait.geneid, myTrait.symbol), target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % myTrait.geneid, Class="fs12 fwn"),
+ '. GN ranked all genes in the ', HT.Href(text=searchDBName,url=searchDBLink,target="_blank", Class="fwn"),' database by the %s.' % methodDict[method],
+ ' The top %d probes or probesets in the ' % returnNumber, HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank", Class="fwn"),
+ ' database corresponding to the top genes ranked by the %s are displayed.' %( methodDict[method]),
+ ' You can resort this list using the small arrowheads in the top row.' )
+
+ elif identification:
+ info = HT.Paragraph('Values of %s were compared to all %d traits in ' % (identification, totalTraits),
+ HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank",Class="fwn"),
+ ' database. The TOP %d correlations ranked by the %s are displayed.' % (returnNumber,methodDict[method]),
+ ' You can resort this list using the small arrowheads in the top row.')
+
+ else:
+ info = HT.Paragraph('Trait values were compared to all values in ',
+ HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank",Class="fwn"),
+ ' database. The TOP %d correlations ranked by the %s are displayed.' % (returnNumber,methodDict[method]),
+ ' You can resort this list using the small arrowheads in the top row.')
+
+ if db.type=="Geno":
+ info.append(HT.BR(),HT.BR(),'Clicking on the Locus will open the genotypes data for that locus. Click on the correlation to see a scatter plot of the trait data.')
+ elif db.type=="Publish":
+ info.append(HT.BR(),HT.BR(),'Clicking on the record ID will open the published phenotype data for that publication. Click on the correlation to see a scatter plot of the trait data. ')
+ elif db.type=="ProbeSet":
+ info.append(HT.BR(),'Click the correlation values to generate scatter plots. Select the Record ID to open the Trait Data and Analysis form. Select the symbol to open NCBI Entrez.')
+ else:
+ pass
+
+
+ return info
+
+
+ def createExcelFileWithTitleAndFooter(self, workbook=None, identification=None, db=None, returnNumber=None):
+
+ worksheet = workbook.add_worksheet()
+
+ titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray")
+
+ ##Write title Info
+ # Modified by Hongqiang Li
+ worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle)
+ worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle)
+ worksheet.write([2, 0], "Trait : %s" % identification, titleStyle)
+ worksheet.write([3, 0], "Database : %s" % db.fullname, titleStyle)
+ worksheet.write([4, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle)
+ worksheet.write([5, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle)
+ worksheet.write([6, 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)
+ #Write footer info
+ worksheet.write([9 + returnNumber, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle)
+ worksheet.write([10 + returnNumber, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle)
+
+ return worksheet
+
+
+ def getTableHeaderForGeno(self, method=None, worksheet=None, newrow=None, headingStyle=None):
+
+ tblobj_header = []
+
+ if method in ["1","3","4"]:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb"), sort=0),
+ THCell(HT.TD('Record', HT.BR(), 'ID', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text='Record ID', idx=1),
+ THCell(HT.TD('Location', HT.BR(), 'Chr and Mb', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text='Location (Chr and Mb)', idx=2),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample r", idx=3),
+ THCell(HT.TD('N',HT.BR(),'Cases',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="N Cases", idx=4),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample p(r)", idx=5)]]
+
+ for ncol, item in enumerate(['Record ID', 'Location (Chr, Mb)', 'Sample r', 'N Cases', 'Sample p(r)']):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+ else:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb"), sort=0),
+ THCell(HT.TD('Record', HT.BR(), 'ID', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text='Record ID', idx=1),
+ THCell(HT.TD('Location', HT.BR(), 'Chr and Mb', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text='Location (Chr and Mb)', idx=2),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample rho", idx=3),
+ THCell(HT.TD('N',HT.BR(),'Cases',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="N Cases", idx=4),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample p(rho)", idx=5)]]
+
+ for ncol, item in enumerate(['Record ID', 'Location (Chr, Mb)', 'Sample rho', 'N Cases', 'Sample p(rho)']):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+
+ return tblobj_header, worksheet
+
+
+ def getTableBodyForGeno(self, traitList, formName=None, worksheet=None, newrow=None, corrScript=None):
+
+ tblobj_body = []
+
+ for thisTrait in traitList:
+ tr = []
+
+ trId = str(thisTrait)
+
+ corrScript.append('corrArray["%s"] = {corr:%1.4f};' % (trId, thisTrait.corr))
+
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showTrait('%s', '%s')" % (formName, thisTrait.name), Class="fs12 fwn ffl"),align="left", Class="fs12 fwn ffl b1 c222"), text=thisTrait.name, val=thisTrait.name.upper()))
+
+ #XZ: trait_location_value is used for sorting
+ trait_location_repr = '--'
+ trait_location_value = 1000000
+
+ if 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, Class="fs12 fwn b1 c222", nowrap="on"), trait_location_repr, trait_location_value))
+
+
+ repr='%3.3f' % thisTrait.corr
+ tr.append(TDCell(HT.TD(HT.Href(text=repr, url="javascript:showCorrPlot('%s', '%s')" % (formName, thisTrait.name), Class="fs12 fwn ffl"), Class="fs12 fwn ffl b1 c222", nowrap='ON', align='right'),repr,abs(thisTrait.corr)))
+
+ repr = '%d' % thisTrait.nOverlap
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222",align='right'),repr,thisTrait.nOverlap))
+
+ repr = webqtlUtil.SciFloat(thisTrait.corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.corrPValue))
+
+ tblobj_body.append(tr)
+
+ for ncol, item in enumerate([thisTrait.name, trait_location_repr, thisTrait.corr, thisTrait.nOverlap, thisTrait.corrPValue]):
+ worksheet.write([newrow, ncol], item)
+ newrow += 1
+
+ return tblobj_body, worksheet, corrScript
+
+
+ def getTableHeaderForPublish(self, method=None, worksheet=None, newrow=None, headingStyle=None):
+
+ tblobj_header = []
+
+ if method in ["1","3","4"]:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), sort=0),
+ THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Record ID", idx=1),
+ THCell(HT.TD('Phenotype', HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Phenotype", idx=2),
+ THCell(HT.TD('Authors', HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Authors", idx=3),
+ THCell(HT.TD('Year', HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Year", idx=4),
+ THCell(HT.TD('Max',HT.BR(), 'LRS', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Max LRS", idx=5),
+ THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Max LRS Location", idx=6),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample r", idx=7),
+ THCell(HT.TD('N',HT.BR(),'Cases',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="N Cases", idx=8),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample p(r)", idx=9)]]
+
+ for ncol, item in enumerate(["Record", "Phenotype", "Authors", "Year", "Pubmed Id", "Max LRS", "Max LRS Location (Chr: Mb)", "Sample r", "N Cases", "Sample p(r)"]):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+ else:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), sort=0),
+ THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Record ID", idx=1),
+ THCell(HT.TD('Phenotype', HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Phenotype", idx=2),
+ THCell(HT.TD('Authors', HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Authors", idx=3),
+ THCell(HT.TD('Year', HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Year", idx=4),
+ THCell(HT.TD('Max',HT.BR(), 'LRS', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Max LRS", idx=5),
+ THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="Max LRS Location", idx=6),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample rho", idx=7),
+ THCell(HT.TD('N',HT.BR(),'Cases',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="N Cases", idx=8),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample p(rho)", idx=9)]]
+
+ for ncol, item in enumerate(["Record", "Phenotype", "Authors", "Year", "Pubmed Id", "Max LRS", "Max LRS Location (Chr: Mb)", "Sample rho", "N Cases", "Sample p(rho)"]):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+
+ return tblobj_header, worksheet
+
+
+ def getTableBodyForPublish(self, traitList, formName=None, worksheet=None, newrow=None, corrScript=None, species=''):
+
+ tblobj_body = []
+
+ for thisTrait in traitList:
+ tr = []
+
+ trId = str(thisTrait)
+
+ corrScript.append('corrArray["%s"] = {corr:%1.4f};' % (trId, thisTrait.corr))
+
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showTrait('%s', '%s')" % (formName, thisTrait.name), Class="fs12 fwn"), nowrap="yes",align="center", Class="fs12 fwn b1 c222"),str(thisTrait.name), thisTrait.name))
+
+ 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
+
+ tr.append(TDCell(HT.TD(PhenotypeString, Class="fs12 fwn b1 c222"), PhenotypeString, PhenotypeString.upper()))
+
+ tr.append(TDCell(HT.TD(thisTrait.authors, Class="fs12 fwn b1 c222 fsI"),thisTrait.authors, thisTrait.authors.strip().upper()))
+
+ try:
+ PubMedLinkText = myear = repr = int(thisTrait.year)
+ except:
+ PubMedLinkText = repr = "--"
+ myear = 0
+ if thisTrait.pubmed_id:
+ PubMedLink = HT.Href(text= repr,url= webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id,target='_blank', Class="fs12 fwn")
+ else:
+ PubMedLink = repr
+
+ tr.append(TDCell(HT.TD(PubMedLink, Class="fs12 fwn b1 c222", align='center'), repr, myear))
+
+ #LRS and its location
+ LRS_score_repr = '--'
+ LRS_score_value = 0
+ LRS_location_repr = '--'
+ LRS_location_value = 1000000
+ LRS_flag = 1
+
+ #Max LRS and its Locus location
+ if 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_score_repr = '%3.1f' % thisTrait.lrs
+ LRS_score_value = thisTrait.lrs
+ LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) )
+ LRS_flag = 0
+
+ #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, thisTrait.db.shortname, thisTrait.name), Class="fs12 fwn"), Class="fs12 fwn ffl b1 c222", align='right', nowrap="on"),LRS_score_repr, LRS_score_value))
+ tr.append(TDCell(HT.TD(LRS_score_repr, Class="fs12 fwn b1 c222", align='right', nowrap="on"), LRS_score_repr, LRS_score_value))
+ tr.append(TDCell(HT.TD(LRS_location_repr, Class="fs12 fwn b1 c222"), LRS_location_repr, LRS_location_value))
+
+ if LRS_flag:
+ tr.append(TDCell(HT.TD(LRS_score_repr, Class="fs12 fwn b1 c222"), LRS_score_repr, LRS_score_value))
+ tr.append(TDCell(HT.TD(LRS_location_repr, Class="fs12 fwn b1 c222"), LRS_location_repr, LRS_location_value))
+
+ repr = '%3.4f' % thisTrait.corr
+ tr.append(TDCell(HT.TD(HT.Href(text=repr,url="javascript:showCorrPlot('%s', '%s')" % (formName,thisTrait.name), Class="fs12 fwn"), Class="fs12 fwn b1 c222", align='right',nowrap="on"), repr, abs(thisTrait.corr)))
+
+ repr = '%d' % thisTrait.nOverlap
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.nOverlap))
+
+ repr = webqtlUtil.SciFloat(thisTrait.corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.corrPValue))
+
+ tblobj_body.append(tr)
+
+ for ncol, item in enumerate([thisTrait.name, PhenotypeString, thisTrait.authors, thisTrait.year, thisTrait.pubmed_id, LRS_score_repr, LRS_location_repr, thisTrait.corr, thisTrait.nOverlap, thisTrait.corrPValue]):
+ worksheet.write([newrow, ncol], item)
+ newrow += 1
+
+ return tblobj_body, worksheet, corrScript
+
+
+ def getTableHeaderForProbeSet(self, method=None, worksheet=None, newrow=None, headingStyle=None):
+
+ tblobj_header = []
+
+ if method in ["1","3","4"]:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0),
+ THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Record ID", idx=1),
+ THCell(HT.TD('Gene',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Gene ID", idx=2),
+ THCell(HT.TD('Homologene',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Homologene ID", idx=3),
+ THCell(HT.TD('Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Symbol", idx=4),
+ THCell(HT.TD('Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Description", idx=5),
+ THCell(HT.TD('Location',HT.BR(), 'Chr and Mb', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Location (Chr: Mb)", idx=6),
+ THCell(HT.TD('Mean',HT.BR(),'Expr',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Mean Expr", idx=7),
+ THCell(HT.TD('Max',HT.BR(),'LRS',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Max LRS", idx=8),
+ THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Max LRS Location (Chr: Mb)", idx=9),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample r", idx=10),
+ THCell(HT.TD('N',HT.BR(),'Cases',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="N Cases", idx=11),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample p(r)", idx=12),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Lit',HT.BR(), 'Corr', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#literatureCorr"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Lit Corr", idx=13),
+ #XZ, 09/22/2008: tissue correlation
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Tissue r", idx=14),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'p(r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Tissue p(r)", idx=15)]]
+
+ for ncol, item in enumerate(['Record', 'Gene ID', 'Homologene ID', 'Symbol', 'Description', 'Location (Chr: Mb)', 'Mean Expr', 'Max LRS', 'Max LRS Location (Chr: Mb)', 'Sample r', 'N Cases', 'Sample p(r)', 'Lit Corr', 'Tissue r', 'Tissue p(r)']):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+ else:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0),
+ THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Record ID", idx=1),
+ THCell(HT.TD('Gene',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Gene ID", idx=2),
+ THCell(HT.TD('Homologene',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Homologene ID", idx=3),
+ THCell(HT.TD('Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Symbol", idx=4),
+ THCell(HT.TD('Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Description", idx=5),
+ THCell(HT.TD('Location',HT.BR(), 'Chr and Mb', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Location (Chr: Mb)", idx=6),
+ THCell(HT.TD('Mean',HT.BR(),'Expr',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Mean Expr", idx=7),
+ THCell(HT.TD('Max',HT.BR(),'LRS',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Max LRS", idx=8),
+ THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Max LRS Location (Chr: Mb)", idx=9),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample rho", idx=10),
+ THCell(HT.TD('N',HT.BR(),'Cases',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="N Cases", idx=11),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Sample p(rho)", idx=12),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Lit',HT.BR(), 'Corr', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#literatureCorr"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Lit Corr", idx=13),
+ #XZ, 09/22/2008: tissue correlation
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Tissue rho", idx=14),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="Tissue p(rho)", idx=15)]]
+
+ for ncol, item in enumerate(['Record ID', 'Gene ID', 'Homologene ID', 'Symbol', 'Description', 'Location (Chr: Mb)', 'Mean Expr', 'Max LRS', 'Max LRS Location (Chr: Mb)', 'Sample rho', 'N Cases', 'Sample p(rho)', 'Lit Corr', 'Tissue rho', 'Tissue p(rho)']):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+ return tblobj_header, worksheet
+
+
+ def getTableBodyForProbeSet(self, traitList=[], primaryTrait=None, formName=None, worksheet=None, newrow=None, corrScript=None, species=''):
+
+ tblobj_body = []
+
+ for thisTrait in traitList:
+
+ if thisTrait.symbol:
+ pass
+ else:
+ thisTrait.symbol = "--"
+
+ 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="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="fs12 fwn")
+
+ tr = []
+
+ trId = str(thisTrait)
+
+ corrScript.append('corrArray["%s"] = {corr:%1.4f};' % (trId, thisTrait.corr))
+
+ #XZ, 12/08/2008: checkbox
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+
+ #XZ, 12/08/2008: probeset name
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showTrait('%s', '%s')" % (formName,thisTrait.name), Class="fs12 fwn"), Class="fs12 fwn b1 c222"), thisTrait.name, thisTrait.name.upper()))
+
+ #XZ, 12/08/2008: gene id
+ if thisTrait.geneid:
+ tr.append(TDCell(None, thisTrait.geneid, val=999))
+ else:
+ tr.append(TDCell(None, thisTrait.geneid, val=999))
+
+ #XZ, 12/08/2008: homologene id
+ if thisTrait.homologeneid:
+ tr.append(TDCell("", thisTrait.homologeneid, val=999))
+ else:
+ tr.append(TDCell("", thisTrait.homologeneid, val=999))
+
+ #XZ, 12/08/2008: gene symbol
+ tr.append(TDCell(HT.TD(symbolurl, Class="fs12 fwn b1 c222 fsI"),thisTrait.symbol, thisTrait.symbol.upper()))
+
+ #XZ, 12/08/2008: description
+ #XZ, 06/05/2009: Rob asked to add probe target description
+ description_string = str(thisTrait.description).strip()
+ 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()
+
+ tr.append(TDCell(HT.TD(description_display, Class="fs12 fwn b1 c222"), description_display, description_display))
+
+ #XZ: trait_location_value is used for sorting
+ trait_location_repr = '--'
+ trait_location_value = 1000000
+
+ if 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, Class="fs12 fwn b1 c222", nowrap="on"), trait_location_repr, trait_location_value))
+
+ """
+ #XZ, 12/08/2008: chromosome number
+ #XZ, 12/10/2008: use Mbvalue to sort chromosome
+ tr.append(TDCell( HT.TD(thisTrait.chr, Class="fs12 fwn b1 c222", align='right'), thisTrait.chr, Mbvalue) )
+
+ #XZ, 12/08/2008: Rob wants 6 digit precision, and we have to deal with that the mb could be None
+ if not thisTrait.mb:
+ tr.append(TDCell(HT.TD(thisTrait.mb, Class="fs12 fwn b1 c222",align='right'), thisTrait.mb, Mbvalue))
+ else:
+ tr.append(TDCell(HT.TD('%.6f' % thisTrait.mb, Class="fs12 fwn b1 c222", align='right'), thisTrait.mb, Mbvalue))
+ """
+
+
+
+ #XZ, 01/12/08: This SQL query is much faster.
+ 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="fs12 fwn ffl b1 c222", align='right', nowrap='ON'),repr, mean))
+
+ #LRS and its location
+ LRS_score_repr = '--'
+ LRS_score_value = 0
+ LRS_location_repr = '--'
+ LRS_location_value = 1000000
+ LRS_flag = 1
+
+ #Max LRS and its Locus location
+ if 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_score_repr = '%3.1f' % thisTrait.lrs
+ LRS_score_value = thisTrait.lrs
+ LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) )
+ LRS_flag = 0
+
+ #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, thisTrait.db.shortname, thisTrait.name), Class="fs12 fwn"), Class="fs12 fwn ffl b1 c222", align='right', nowrap="on"),LRS_score_repr, LRS_score_value))
+ tr.append(TDCell(HT.TD(LRS_score_repr, Class="fs12 fwn b1 c222", align='right', nowrap="on"), LRS_score_repr, LRS_score_value))
+ tr.append(TDCell(HT.TD(LRS_location_repr, Class="fs12 fwn b1 c222", nowrap="on"), LRS_location_repr, LRS_location_value))
+
+ if LRS_flag:
+ tr.append(TDCell(HT.TD(LRS_score_repr, Class="fs12 fwn b1 c222"), LRS_score_repr, LRS_score_value))
+ tr.append(TDCell(HT.TD(LRS_location_repr, Class="fs12 fwn b1 c222"), LRS_location_repr, LRS_location_value))
+
+
+ #XZ, 12/08/2008: generic correlation
+ repr='%3.3f' % thisTrait.corr
+ tr.append(TDCell(HT.TD(HT.Href(text=repr, url="javascript:showCorrPlot('%s', '%s')" % (formName, thisTrait.name), Class="fs12 fwn ffl"), Class="fs12 fwn ffl b1 c222", align='right'),repr,abs(thisTrait.corr)))
+
+ #XZ, 12/08/2008: number of overlaped cases
+ repr = '%d' % thisTrait.nOverlap
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.nOverlap))
+
+ #XZ, 12/08/2008: p value of genetic correlation
+ repr = webqtlUtil.SciFloat(thisTrait.corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.corrPValue))
+
+ #XZ, 12/08/2008: literature correlation
+ LCorr = 0.0
+ LCorrStr = "--"
+ if hasattr(thisTrait, 'LCorr') and thisTrait.LCorr:
+ LCorr = thisTrait.LCorr
+ LCorrStr = "%2.3f" % thisTrait.LCorr
+ tr.append(TDCell(HT.TD(LCorrStr, Class="fs12 fwn b1 c222", align='right'), LCorrStr, abs(LCorr)))
+
+ #XZ, 09/22/2008: tissue correlation.
+ TCorr = 0.0
+ TCorrStr = "--"
+ #XZ, 11/20/2008: need to pass two geneids: input_trait_mouse_geneid and thisTrait.mouse_geneid
+ if hasattr(thisTrait, 'tissueCorr') and thisTrait.tissueCorr:
+ TCorr = thisTrait.tissueCorr
+ TCorrStr = "%2.3f" % thisTrait.tissueCorr
+ # NL, 07/19/2010: add a new parameter rankOrder for js function 'showTissueCorrPlot'
+ rankOrder = thisTrait.rankOrder
+ TCorrPlotURL = "javascript:showTissueCorrPlot('%s','%s','%s',%d)" %(formName, primaryTrait.symbol, thisTrait.symbol,rankOrder)
+ tr.append(TDCell(HT.TD(HT.Href(text=TCorrStr, url=TCorrPlotURL, Class="fs12 fwn ff1"), Class="fs12 fwn ff1 b1 c222", align='right'), TCorrStr, abs(TCorr)))
+ else:
+ tr.append(TDCell(HT.TD(TCorrStr, Class="fs12 fwn b1 c222", align='right'), TCorrStr, abs(TCorr)))
+
+ #XZ, 12/08/2008: p value of tissue correlation
+ TPValue = 1.0
+ TPValueStr = "--"
+ if hasattr(thisTrait, 'tissueCorr') and thisTrait.tissuePValue: #XZ, 09/22/2008: thisTrait.tissuePValue can't be used here because it could be 0
+ TPValue = thisTrait.tissuePValue
+ TPValueStr = "%2.3f" % thisTrait.tissuePValue
+ tr.append(TDCell(HT.TD(TPValueStr, Class="fs12 fwn b1 c222", align='right'), TPValueStr, TPValue))
+
+ tblobj_body.append(tr)
+
+ for ncol, item in enumerate([thisTrait.name, thisTrait.geneid, thisTrait.homologeneid, thisTrait.symbol, thisTrait.description, trait_location_repr, mean, LRS_score_repr, LRS_location_repr, thisTrait.corr, thisTrait.nOverlap, thisTrait.corrPValue, LCorr, TCorr, TPValue]):
+ worksheet.write([newrow, ncol], item)
+
+ newrow += 1
+
+ return tblobj_body, worksheet, corrScript
diff --git a/web/webqtl/correlation/PartialCorrDBPage.py b/web/webqtl/correlation/PartialCorrDBPage.py
new file mode 100755
index 00000000..ecd1e623
--- /dev/null
+++ b/web/webqtl/correlation/PartialCorrDBPage.py
@@ -0,0 +1,1359 @@
+import string
+import cPickle
+import os
+import pyXLWriter as xl
+
+from htmlgen import HTMLgen2 as HT
+
+from base import webqtlConfig
+#import webqtlData
+from utility.THCell import THCell
+from utility.TDCell import TDCell
+from base.webqtlTrait import webqtlTrait
+from base.webqtlDataset import webqtlDataset
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from CorrelationPage import CorrelationPage
+import correlationFunction
+from dbFunction import webqtlDatabaseFunction
+
+
+#########################################
+# Partial Correlation Dataset Page
+#########################################
+
+
+class PartialCorrDBPage(CorrelationPage):
+
+ corrMinInformative = 4
+
+ def __init__(self, fd):
+
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+
+ primaryTraitString = fd.formdata.getvalue('primaryTrait')
+ primaryTrait = (webqtlTrait(fullname=primaryTraitString, cursor=self.cursor))
+
+ controlTraitsString = fd.formdata.getvalue('controlTraits')
+ controlTraitsList = list(string.split(controlTraitsString,','))
+ controlTraits = []
+ for item in controlTraitsList:
+ controlTraits.append(webqtlTrait(fullname=item, cursor=self.cursor))
+
+ #XZ, 3/16/2010: variable RISet must be pass by the form
+ RISet = fd.RISet
+ #XZ, 12/12/2008: get species infomation
+ species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet)
+
+ #XZ, 09/18/2008: get all information about the user selected database.
+ self.target_db_name = fd.formdata.getvalue('database2')
+
+ try:
+ self.db = webqtlDataset(self.target_db_name, self.cursor)
+ except:
+ heading = "Partial Correlation Table"
+ detail = ["The database you just requested has not been established yet."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, 09/18/2008: check if user has the authority to get access to the database.
+ if self.db.type == 'ProbeSet':
+ self.cursor.execute('SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM ProbeSetFreeze WHERE Name = "%s"' % self.target_db_name)
+ indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0]
+
+ if confidential == 1:
+ access_to_confidential_dataset = 0
+
+ #for the dataset that confidentiality is 1
+ #1. 'admin' and 'root' can see all of the dataset
+ #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table)
+ if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']:
+ access_to_confidential_dataset = 1
+ else:
+ AuthorisedUsersList=AuthorisedUsers.split(',')
+ if AuthorisedUsersList.__contains__(self.userName):
+ access_to_confidential_dataset = 1
+
+ if not access_to_confidential_dataset:
+ #Error, Confidential Database
+ heading = "Partial Correlation Table"
+ detail = ["The %s database you selected is not open to the public at this time, please go back and select another database." % indFullName]
+ self.error(heading=heading,detail=detail,error="Confidential Database")
+ return
+
+
+ primaryTrait.retrieveData()
+ _primarystrains, _primaryvals, _primaryvars = primaryTrait.exportInformative()
+
+ controlTraitNames = fd.formdata.getvalue('controlTraits')
+ _controlstrains,_controlvals,_controlvars,_controlNs = correlationFunction.controlStrains(controlTraitNames,_primarystrains)
+
+ ## If the strains for which each of the control traits and the primary trait have values are not identical,
+ ## we must remove from the calculation all vlaues for strains that are not present in each. Without doing this,
+ ## undesirable biases would be introduced.
+
+ common_primary_control_strains = _primarystrains #keep _primarystrains
+ fixed_primary_vals = _primaryvals #keep _primaryvals
+ fixed_control_vals = _controlvals
+
+ allsame = True
+ ##allsame is boolean for whether or not primary and control trait have values for the same strains
+ for i in _controlstrains:
+ if _primarystrains != i:
+ allsame=False
+ break
+
+ if not allsame:
+ common_primary_control_strains, fixed_primary_vals, fixed_control_vals, _vars, _controlvars = correlationFunction.fixStrains(_primarystrains,_controlstrains,_primaryvals,_controlvals,_primaryvars,_controlvars)
+
+ N = len(common_primary_control_strains)
+ if N < self.corrMinInformative:
+ heading = "Partial Correlation Table"
+ detail = ['Fewer than %d strain data were entered for %s data set. No calculation of correlation has been attempted.' % (self.corrMinInformative, RISet)]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ: We should check the value of control trait and primary trait here.
+ nameOfIdenticalTraits = correlationFunction.findIdenticalTraits ( fixed_primary_vals, primaryTraitString, fixed_control_vals, controlTraitsList )
+ if nameOfIdenticalTraits:
+ heading = "Partial Correlation Table"
+ detail = ['%s and %s have same values for the %s strains that will be used to calculate partial correlation (common for all primary and control traits). In such case, partial correlation can NOT be calculated. Please re-select your traits.' % (nameOfIdenticalTraits[0], nameOfIdenticalTraits[1], len(fixed_primary_vals))]
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ #XZ, 09/28/2008: if user select "1", then display 1, 3 and 4.
+ #XZ, 09/28/2008: if user select "2", then display 2, 3 and 5.
+ #XZ, 09/28/2008: if user select "3", then display 1, 3 and 4.
+ #XZ, 09/28/2008: if user select "4", then display 1, 3 and 4.
+ #XZ, 09/28/2008: if user select "5", then display 2, 3 and 5.
+ methodDict = {"1":"Genetic Correlation (Pearson's r)","2":"Genetic Correlation (Spearman's rho)","3":"SGO Literature Correlation","4":"Tissue Correlation (Pearson's r)", "5":"Tissue Correlation (Spearman's rho)"}
+ self.method = fd.formdata.getvalue('method')
+ if self.method not in ("1","2","3","4","5"):
+ self.method = "1"
+
+ self.returnNumber = int(fd.formdata.getvalue('criteria'))
+
+ myTrait = primaryTrait
+ myTrait.retrieveInfo()
+
+ # We will not get Literature Correlations if there is no GeneId because there is nothing to look against
+ try:
+ input_trait_GeneId = myTrait.geneid
+ except:
+ input_trait_GeneId = None
+
+ # We will not get Tissue Correlations if there is no gene symbol because there is nothing to look against
+ try:
+ input_trait_symbol = myTrait.symbol
+ except:
+ input_trait_symbol = None
+
+
+ #XZ, 12/12/2008: if the species is rat or human, translate the geneid to mouse geneid
+ input_trait_mouse_geneid = self.translateToMouseGeneID(species, input_trait_GeneId)
+
+ #XZ: As of Nov/13/2010, this dataset is 'UTHSC Illumina V6.2 RankInv B6 D2 average CNS GI average (May 08)'
+ TissueProbeSetFreezeId = 1
+
+
+ #XZ, 09/22/2008: If we need search by GeneId,
+ #XZ, 09/22/2008: we have to check if this GeneId is in the literature or tissue correlation table.
+ #XZ, 10/15/2008: We also to check if the selected database is probeset type.
+ if self.method == "3" or self.method == "4" or self.method == "5":
+ if self.db.type != "ProbeSet":
+ self.error(heading="Wrong correlation type",detail="It is not possible to compute the %s between your trait and data in this %s database. Please try again after selecting another type of correlation." % (methodDict[self.method],self.db.name),error="Correlation Type Error")
+ return
+
+ """
+ if not input_trait_GeneId:
+ self.error(heading="No Associated GeneId",detail="This trait has no associated GeneId, so we are not able to show any literature or tissue related information.",error="No GeneId Error")
+ return
+ """
+
+ #XZ: We have checked geneid did exist
+
+ if self.method == "3":
+ if not input_trait_GeneId or not self.checkForLitInfo(input_trait_mouse_geneid):
+ self.error(heading="No Literature Info",detail="This gene does not have any associated Literature Information.",error="Literature Correlation Error")
+ return
+
+ if self.method == "4" or self.method == "5":
+ if not input_trait_symbol:
+ self.error(heading="No Tissue Correlation Information",detail="This gene does not have any associated Tissue Correlation Information.",error="Tissue Correlation Error")
+ return
+
+ if not self.checkSymbolForTissueCorr(TissueProbeSetFreezeId, myTrait.symbol):
+ self.error(heading="No Tissue Correlation Information",detail="This gene does not have any associated Tissue Correlation Information.",error="Tissue Correlation Error")
+ return
+
+#######################################################################################################################################
+
+ nnCorr = len(fixed_primary_vals)
+
+ #XZ: Use the fast method only for probeset dataset, and this dataset must have been created.
+ #XZ: Otherwise, use original method
+
+ useFastMethod = False
+
+ if self.db.type == "ProbeSet":
+ DatabaseFileName = self.getFileName( target_db_name=self.target_db_name )
+ DirectoryList = os.listdir(webqtlConfig.TEXTDIR) # List of existing text files. Used to check if a text file already exists
+ if DatabaseFileName in DirectoryList:
+ useFastMethod = True
+
+ if useFastMethod:
+ totalTraits, allcorrelations = self.getPartialCorrelationsFast(common_primary_control_strains , fixed_primary_vals, fixed_control_vals, nnCorr, DatabaseFileName, species, input_trait_GeneId, input_trait_symbol, TissueProbeSetFreezeId)
+
+ if totalTraits == 0:
+ useFastMethod = False
+
+ #XZ, 01/08/2009: use the original method to retrieve from database and compute.
+ if not useFastMethod:
+ totalTraits, allcorrelations = self.getPartialCorrelationsNormal(common_primary_control_strains, fixed_primary_vals, fixed_control_vals, nnCorr, species, input_trait_GeneId, input_trait_symbol,TissueProbeSetFreezeId)
+
+#############################################################
+
+ if self.method == "3" and input_trait_GeneId:
+ allcorrelations.sort(self.cmpLitCorr)
+ elif self.method in ["4","5"] and input_trait_GeneId:
+ allcorrelations.sort(self.cmpLitCorr)
+ else:
+ allcorrelations.sort(self.cmpPartialCorrPValue)
+
+ #XZ, 09/20/2008: we only need the top ones.
+ self.returnNumber = min(self.returnNumber,len(allcorrelations))
+ allcorrelations = allcorrelations[:self.returnNumber]
+
+ addLiteratureCorr = False
+ addTissueCorr = False
+
+ traitList = []
+ for item in allcorrelations:
+ thisTrait = webqtlTrait(db=self.db, name=item[0], cursor=self.cursor)
+ thisTrait.retrieveInfo()
+
+ thisTrait.Name = item[0]
+ thisTrait.NOverlap = item[1]
+
+ thisTrait.partial_corr = item[2]
+ thisTrait.partial_corrPValue = item[3]
+
+ thisTrait.corr = item[4]
+ thisTrait.corrPValue = item[5]
+ # NL, 07/19/2010
+ # js function changed, add a new parameter rankOrder for js function 'showTissueCorrPlot'
+ rankOrder = 0;
+ if self.method in ["2","5"]:
+ rankOrder = 1;
+ thisTrait.rankOrder = rankOrder
+
+ #XZ, 26/09/2008: Method is 4 or 5. Have fetched tissue corr, but no literature correlation yet.
+ if len(item) == 8:
+ thisTrait.tissueCorr = item[6]
+ thisTrait.tissuePValue = item[7]
+ addLiteratureCorr = True
+
+ #XZ, 26/09/2008: Method is 3, Have fetched literature corr, but no tissue corr yet.
+ elif len(item) == 7:
+ thisTrait.LCorr = item[6]
+ thisTrait.mouse_geneid = self.translateToMouseGeneID(species, thisTrait.geneid)
+ addTissueCorr = True
+
+ #XZ, 26/09/2008: Method is 1 or 2. Have NOT fetched literature corr and tissue corr yet.
+ # Phenotype data will not have geneid, and neither will some probes
+ # we need to handle this because we will get an attribute error
+ else:
+ if input_trait_mouse_geneid and self.db.type=="ProbeSet":
+ addLiteratureCorr = True
+ if input_trait_symbol and self.db.type=="ProbeSet":
+ addTissueCorr = True
+
+ traitList.append(thisTrait)
+
+ if addLiteratureCorr:
+ traitList = self.getLiteratureCorrelationByList(input_trait_mouse_geneid, species, traitList)
+ if addTissueCorr:
+ traitList = self.getTissueCorrelationByList(primaryTraitSymbol=input_trait_symbol, traitList=traitList,TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=self.method)
+
+########################################################
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ mainfmName = webqtlUtil.genRandStr("fm_")
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name= mainfmName, submit=HT.Input(type='hidden'))
+ hddn = {'FormID':'showDatabase', 'ProbeSetID':'_','database':self.target_db_name, 'CellID':'_', 'RISet':RISet, 'identification':fd.identification}
+
+ if myTrait:
+ hddn['fullname']=str(myTrait)
+
+
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ #XZ, 11/21/2008: add two parameters to form
+ form.append(HT.Input(name="X_geneSymbol", value="", type='hidden'))
+ form.append(HT.Input(name="Y_geneSymbol", value="", type='hidden'))
+
+ #XZ, 3/11/2010: add one parameter to record if the method is rank order.
+
+ form.append(HT.Input(name="rankOrder", value="%s" % rankOrder, type='hidden'))
+
+ form.append(HT.Input(name="TissueProbeSetFreezeId", value="%s" % TissueProbeSetFreezeId, type='hidden'))
+
+
+ ####################################
+ # generate the info on top of page #
+ ####################################
+
+ info_form = self.getFormForPrimaryAndControlTraits (primaryTrait, controlTraits)
+ info = self.getTopInfo(myTrait=myTrait, method=self.method, db=self.db, target_db_name=self.target_db_name, returnNumber=self.returnNumber, methodDict=methodDict, totalTraits=totalTraits, identification=fd.identification )
+
+ ##############
+ # Excel file #
+ ##############
+ filename= webqtlUtil.genRandStr("Corr_")
+ xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button')
+ # Create a new Excel workbook
+ workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename))
+ headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white")
+
+ #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines.
+ worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, identification=fd.identification, db=self.db, returnNumber=self.returnNumber)
+
+ newrow = 7
+
+
+
+#####################################################################
+
+ mintmap = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'showIntMap');" % mainfmName)
+ mintmap_img = HT.Image("/images/multiple_interval_mapping1_final.jpg", name='mintmap', alt="Multiple Interval Mapping", title="Multiple Interval Mapping", style="border:none;")
+ mintmap.append(mintmap_img)
+ mcorr = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'compCorr');" % mainfmName)
+ mcorr_img = HT.Image("/images/compare_correlates2_final.jpg", alt="Compare Correlates", title="Compare Correlates", style="border:none;")
+ mcorr.append(mcorr_img)
+ cormatrix = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'corMatrix');" % mainfmName)
+ 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)
+ networkGraph = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'networkGraph');" % mainfmName)
+ networkGraph_img = HT.Image("/images/network_graph1_final.jpg", name='mintmap', alt="Network Graphs", title="Network Graphs", style="border:none;")
+ networkGraph.append(networkGraph_img)
+ heatmap = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'heatmap');" % mainfmName)
+ 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)
+ partialCorr = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'partialCorrInput');" % mainfmName)
+ partialCorr_img = HT.Image("/images/partial_correlation_final.jpg", name='partialCorr', alt="Partial Correlation", title="Partial Correlation", style="border:none;")
+ partialCorr.append(partialCorr_img)
+ addselect = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (RISet, mainfmName))
+ addselect_img = HT.Image("/images/add_collection1_final.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;")
+ addselect.append(addselect_img)
+ selectall = HT.Href(url="#redirect", onClick="checkAll(document.getElementsByName('%s')[0]);" % mainfmName)
+ selectall_img = HT.Image("/images/select_all2_final.jpg", name="selectall", alt="Select All", title="Select All", style="border:none;")
+ selectall.append(selectall_img)
+ selectinvert = HT.Href(url="#redirect", onClick = "checkInvert(document.getElementsByName('%s')[0]);" % mainfmName)
+ selectinvert_img = HT.Image("/images/invert_selection2_final.jpg", name="selectinvert", alt="Invert Selection", title="Invert Selection", style="border:none;")
+ selectinvert.append(selectinvert_img)
+ reset = HT.Href(url="#redirect", onClick="checkNone(document.getElementsByName('%s')[0]); return false;" % mainfmName)
+ reset_img = HT.Image("/images/select_none2_final.jpg", alt="Select None", title="Select None", style="border:none;")
+ reset.append(reset_img)
+ selecttraits = HT.Input(type='button' ,name='selecttraits',value='Select Traits', onClick="checkTraits(this.form);",Class="button")
+ selectgt = HT.Input(type='text' ,name='selectgt',value='-1.0', size=6,maxlength=10,onChange="checkNumeric(this,1.0,'-1.0','gthan','greater than filed')")
+ selectlt = HT.Input(type='text' ,name='selectlt',value='1.0', size=6,maxlength=10,onChange="checkNumeric(this,-1.0,'1.0','lthan','less than field')")
+ selectandor = HT.Select(name='selectandor')
+ selectandor.append(('AND','and'))
+ selectandor.append(('OR','or'))
+ selectandor.selected.append('AND')
+
+ chrMenu = HT.Input(type='hidden',name='chromosomes',value='all')
+
+ corrHeading = HT.Paragraph('Partial Correlation Table', Class="title")
+
+
+ pageTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="100%", border=0, align="Left")
+ containerTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="90%",border=0, align="Left")
+
+ optionsTable = HT.TableLite(cellSpacing=2, cellPadding=0,width="320", height="80", border=0, align="Left")
+ optionsTable.append(HT.TR(HT.TD(selectall), HT.TD(reset), HT.TD(selectinvert), HT.TD(addselect), align="left"))
+ optionsTable.append(HT.TR(HT.TD(" "*1,"Select"), HT.TD("Deselect"), HT.TD(" "*1,"Invert"), HT.TD(" "*3,"Add")))
+ containerTable.append(HT.TR(HT.TD(optionsTable)))
+
+ functionTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="480",height="80", border=0, align="Left")
+ functionRow = HT.TR(HT.TD(networkGraph, width="16.7%"), HT.TD(cormatrix, width="16.7%"), HT.TD(partialCorr, width="16.7%"), HT.TD(mcorr, width="16.7%"), HT.TD(mintmap, width="16.7%"), HT.TD(heatmap), align="left")
+ labelRow = HT.TR(HT.TD(" "*1,HT.Text("Graph")), HT.TD(" "*1,HT.Text("Matrix")), HT.TD(" "*1,HT.Text("Partial")), HT.TD(HT.Text("Compare")), HT.TD(HT.Text("QTL Map")), HT.TD(HT.Text(text="Heat Map")))
+ functionTable.append(functionRow, labelRow)
+ containerTable.append(HT.TR(HT.TD(functionTable), HT.BR()))
+
+ moreOptions = HT.Input(type='button',name='options',value='More Options', onClick="",Class="toggle")
+ fewerOptions = HT.Input(type='button',name='options',value='Fewer Options', onClick="",Class="toggle")
+
+ if (fd.formdata.getvalue('showHideOptions') == 'less'):
+ containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(fewerOptions, Class="toggleShowHide"))))
+ containerTable.append(HT.TR(HT.TD(" ")))
+ else:
+ containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(moreOptions, Class="toggleShowHide"))))
+ containerTable.append(HT.TR(HT.TD(" ")))
+
+ containerTable.append(HT.TR(HT.TD(HT.Span(selecttraits,' with partial r > ',selectgt, ' ',selectandor, ' r < ',selectlt,Class="bd1 cbddf fs11")), style="display:none;", Class="extra_options"))
+
+
+ tblobj = {}
+
+
+ if self.db.type=="Geno":
+
+ containerTable.append(HT.TR(HT.TD(xlsUrl, height=40)))
+ pageTable.append(HT.TR(HT.TD(containerTable)))
+
+ tblobj['header'], worksheet = self.getTableHeaderForGeno( method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ corrScript = HT.Script(language="Javascript")
+ corrScript.append("var corrArray = new Array();")
+
+ sortby = self.getSortByValue( calculationMethod = self.method )
+
+ tblobj['body'], worksheet, corrScript = self.getTableBodyForGeno(traitList=traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript)
+
+ workbook.close()
+ 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=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable")
+ pageTable.append(HT.TR(HT.TD(div)))
+ form.append(HT.Input(name='ShowStrains',type='hidden', value =1),
+ HT.Input(name='ShowLine',type='hidden', value =1),
+ HT.P(),pageTable)
+
+ TD_LR.append(corrHeading, info_form, HT.P(), info, form, HT.P())
+
+ self.dict['body'] = str(TD_LR)
+ # updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js
+ self.dict['js1'] = ''
+ self.dict['title'] = 'Partial Correlation Result'
+
+ elif self.db.type=="Publish":
+
+ containerTable.append(HT.TR(HT.TD(xlsUrl, height=40)))
+ pageTable.append(HT.TR(HT.TD(containerTable)))
+
+ tblobj['header'], worksheet = self.getTableHeaderForPublish(method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ sortby = self.getSortByValue( calculationMethod = self.method )
+
+ corrScript = HT.Script(language="Javascript")
+ corrScript.append("var corrArray = new Array();")
+
+ tblobj['body'], worksheet, corrScript = self.getTableBodyForPublish(traitList=traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript)
+
+ workbook.close()
+
+ 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=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable")
+ pageTable.append(HT.TR(HT.TD(div)))
+
+ form.append(
+ HT.Input(name='ShowStrains',type='hidden', value =1),
+ HT.Input(name='ShowLine',type='hidden', value =1),
+ HT.P(),pageTable)
+
+ TD_LR.append(corrHeading, info_form, HT.P(), info, form, HT.P())
+
+ self.dict['body'] = str(TD_LR)
+ #updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js
+ self.dict['js1'] = ''
+ self.dict['title'] = 'Partial Correlation Result'
+
+ elif self.db.type=="ProbeSet":
+
+ tblobj['header'], worksheet = self.getTableHeaderForProbeSet(method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ sortby = self.getSortByValue( calculationMethod = self.method )
+
+ corrScript = HT.Script(language="Javascript")
+ corrScript.append("var corrArray = new Array();")
+
+ tblobj['body'], worksheet, corrScript = self.getTableBodyForProbeSet(traitList=traitList, primaryTrait=myTrait, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript)
+
+ workbook.close()
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ '''
+ #XZ, 07/07/2010: I comment out this block of code.
+ WebGestaltScript = HT.Script(language="Javascript")
+ WebGestaltScript.append("""
+setTimeout('openWebGestalt()', 2000);
+function openWebGestalt(){
+ var thisForm = document['WebGestalt'];
+ makeWebGestaltTree(thisForm, '%s', %d, 'edag_only.php');
+}
+ """ % (mainfmName, len(traitList)))
+ '''
+
+ #XZ: here is the table of traits
+ # 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=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable")
+
+ self.cursor.execute('SELECT GeneChip.GO_tree_value FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % self.db.name)
+ result = self.cursor.fetchone()
+
+ if result:
+ GO_tree_value = result[0]
+
+ if GO_tree_value:
+
+ hddnWebGestalt = {
+ 'id_list':'',
+ 'correlation':'',
+ 'id_value':'',
+ 'llid_list':'',
+ 'id_type':GO_tree_value,
+ 'idtype':'',
+ 'species':'',
+ 'list':'',
+ 'client':''}
+
+ hddnWebGestalt['ref_type'] = hddnWebGestalt['id_type']
+ hddnWebGestalt['cat_type'] = 'GO'
+ hddnWebGestalt['significancelevel'] = 'Top10'
+
+ if species == 'rat':
+ hddnWebGestalt['org'] = 'Rattus norvegicus'
+ elif species == 'human':
+ hddnWebGestalt['org'] = 'Homo sapiens'
+ elif species == 'mouse':
+ hddnWebGestalt['org'] = 'Mus musculus'
+ else:
+ hddnWebGestalt['org'] = ''
+
+ for key in hddnWebGestalt.keys():
+ form.append(HT.Input(name=key, value=hddnWebGestalt[key], type='hidden'))
+
+ #XZ, 01/12/2009: create database menu for 'Add Correlation'
+ self.cursor.execute("""
+ select
+ ProbeSetFreeze.FullName, ProbeSetFreeze.Id, Tissue.name
+ from
+ ProbeSetFreeze, ProbeFreeze, ProbeSetFreeze as ps2, ProbeFreeze as p2, Tissue
+ where
+ ps2.Id = %d
+ and ps2.ProbeFreezeId = p2.Id
+ and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id
+ and (ProbeFreeze.InbredSetId = p2.InbredSetId or (ProbeFreeze.InbredSetId in (1, 3) and p2.InbredSetId in (1, 3)))
+ and p2.ChipId = ProbeFreeze.ChipId
+ and ps2.Id != ProbeSetFreeze.Id
+ and ProbeFreeze.TissueId = Tissue.Id
+ and ProbeSetFreeze.public > %d
+ order by
+ ProbeFreeze.TissueId, ProbeSetFreeze.CreateTime desc
+ """ % (self.db.id, webqtlConfig.PUBLICTHRESH))
+
+ results = self.cursor.fetchall()
+ dbCustomizer = HT.Select(results, name = "customizer")
+ databaseMenuSub = preTissue = ""
+ for item in results:
+ TName, TId, TTissue = item
+ if TTissue != preTissue:
+ if databaseMenuSub:
+ dbCustomizer.append(databaseMenuSub)
+ databaseMenuSub = HT.Optgroup(label = '%s mRNA ------' % TTissue)
+ preTissue = TTissue
+
+ databaseMenuSub.append(item[:2])
+ if databaseMenuSub:
+ dbCustomizer.append(databaseMenuSub)
+ #updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js
+ #variables: filename, strainIds and vals are required by getquerystring function
+ strainIds=self.getStrainIds(species=species, strains=_primarystrains)
+ var1 = HT.Input(name="filename", value=filename, type='hidden')
+ var2 = HT.Input(name="strainIds", value=strainIds, type='hidden')
+ var3 = HT.Input(name="vals", value=_primaryvals, type='hidden')
+ customizerButton = HT.Input(type="button", Class="button", value="Add Correlation", onClick = "xmlhttpPost('%smain.py?FormID=AJAX_table', 'sortable', (getquerystring(this.form)))" % webqtlConfig.CGIDIR)
+
+ containerTable.append(HT.TR(HT.TD(HT.Span(var1,var2,var3,customizerButton, "with", dbCustomizer, Class="bd1 cbddf fs11"), HT.BR(), HT.BR()), style="display:none;", Class="extra_options"))
+
+ #outside analysis part
+ GCATButton = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GCAT');" % mainfmName)
+ GCATButton_img = HT.Image("/images/GCAT_logo_final.jpg", name="GCAT", alt="GCAT", title="GCAT", style="border:none")
+ GCATButton.append(GCATButton_img)
+
+ ODE = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'ODE');" % mainfmName)
+ ODE_img = HT.Image("/images/ODE_logo_final.jpg", name="ode", alt="ODE", title="ODE", style="border:none")
+ ODE.append(ODE_img)
+
+ WebGestalt = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GOTree');" % mainfmName)
+ WebGestalt_img = HT.Image("/images/webgestalt_icon_final.jpg", name="webgestalt", alt="Gene Set Analysis Toolkit", title="Gene Set Analysis Toolkit", style="border:none")
+ WebGestalt.append(WebGestalt_img)
+
+ LinkOutTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="320",height="80", border=0, align="Left")
+ if not GO_tree_value:
+ LinkOutRow = HT.TR(HT.TD(GCATButton, width="50%"), HT.TD(ODE, width="50%"), align="left")
+ LinkOutLabels = HT.TR(HT.TD(" ", HT.Text("GCAT"), width="50%"), HT.TD(" ",HT.Text("ODE"), width="50%"), align="left")
+ else:
+ LinkOutRow = HT.TR(HT.TD(WebGestalt, width="25%"), HT.TD(GCATButton, width="25%"), HT.TD(ODE, width="25%"), align="left")
+ LinkOutLabels = HT.TR(HT.TD(HT.Text("Gene Set")), HT.TD(" "*2, HT.Text("GCAT")), HT.TD(" "*3, HT.Text("ODE")), style="display:none;", Class="extra_options")
+ LinkOutTable.append(LinkOutRow,LinkOutLabels)
+
+ containerTable.append(HT.TR(HT.TD(LinkOutTable), Class="extra_options", style="display:none;"))
+
+ containerTable.append(HT.TR(HT.TD(xlsUrl, HT.BR(), HT.BR(), height=40)))
+
+ pageTable.append(HT.TR(HT.TD(containerTable)))
+
+ pageTable.append(HT.TR(HT.TD(div)))
+
+ if species == 'human':
+ heatmap = ""
+
+ form.append(HT.Input(name='ShowStrains',type='hidden', value =1),
+ HT.Input(name='ShowLine',type='hidden', value =1),
+ info, HT.BR(), pageTable, HT.BR())
+
+ TD_LR.append(corrHeading, info_form, HT.P(), form, HT.P())
+
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = 'Partial Correlation Result'
+ # updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js
+ self.dict['js1'] = ''
+ self.dict['js2'] = 'onLoad="pageOffset()"'
+ self.dict['layer'] = self.generateWarningLayer()
+
+ else:
+ self.dict['body'] = ""
+
+
+
+####################################
+# #
+#Partial CorrelationPage Functions #
+# #
+####################################
+
+
+ def getSortByValue(self, calculationMethod):
+
+ sortby = ("partial_pv", "up")
+
+ if calculationMethod == "3": #XZ: literature correlation
+ sortby = ("lcorr","down")
+ elif calculationMethod == "4" or calculationMethod == "5": #XZ: tissue correlation
+ sortby = ("tissuecorr", "down")
+
+ return sortby
+
+
+ #XZ, 3/31/2010:
+ #A[0] holds trait name.
+ #A[1] holds partial correlation coefficient number.
+ #A[2] holds N.
+ #A[3] holds p value of partial correlation.
+ def cmpPartialCorrPValue (self, A, B):
+ try:
+ if A[3] < B[3]:
+ return -1
+ elif A[3] == B[3]:
+ return 0
+ else:
+ return 1
+ except:
+ return 0
+
+
+ #XZ, 4/1/2010:
+ #A[0] holds trait name.
+ #A[1] holds N.
+ #A[2] holds partial correlation coefficient number.
+ #A[3] holds p value of partial correlation.
+ #A[6] holds literature corr or tissue corr value.
+ #Sort by literature corr or tissue corr first, then by partial corr p value.
+ def cmpLitCorr(self, A, B):
+ try:
+ if abs(A[6]) < abs(B[6]):
+ return 1
+ elif abs(A[6]) == abs(B[6]):
+ if A[3] < B[3]:
+ return -1
+ elif A[3] == B[3]:
+ return 0
+ else:
+ return 1
+ else:
+ return -1
+ except:
+ return 0
+
+
+ def getPartialCorrelationsFast(self, _strains, _vals, _controlvals, nnCorr, DatabaseFileName, species, input_trait_GeneId,gene_symbol,TissueProbeSetFreezeId ):
+ """Calculates and returns correlation coefficients using data from a csv text file."""
+
+ try:
+ allcorrelations = []
+
+ useLit = False
+ if self.method == "3":
+ litCorrs = self.fetchLitCorrelations(species=species, GeneId=input_trait_GeneId, db=self.db, returnNumber=self.returnNumber)
+ useLit = True
+
+ useTissueCorr = False
+ if self.method == "4" or self.method == "5":
+ tissueCorrs = self.fetchTissueCorrelations(db=self.db,primaryTraitSymbol=gene_symbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=self.method, returnNumber=self.returnNumber)
+ useTissueCorr = True
+
+ datasetFile = open(webqtlConfig.TEXTDIR+DatabaseFileName,'r')
+
+ #XZ, 01/08/2009: read the first line
+ line = datasetFile.readline()
+ dataset_strains = webqtlUtil.readLineCSV(line)[1:]
+
+ #XZ, 3/30/2010: This step is critical.
+ good_dataset_strains_index = []
+
+ for i in range(len(_strains)):
+ found_in_dataset_strains = 0
+ for j, one_dataset_strain in enumerate(dataset_strains):
+ if one_dataset_strain == _strains[i]:
+ found_in_dataset_strains = 1
+ good_dataset_strains_index.append(j)
+ break
+
+ if not found_in_dataset_strains:
+ good_dataset_strains_index.append(-99999)
+
+ allTargetTraitNames = []
+ allTargetTraitValues = []
+
+ #XZ, 04/01/2009: If literature corr or tissue corr is selected,
+ #XZ: there is no need to compute partial correlation for all traits.
+ #XZ: If genetic corr is selected, compute partial correlation for all traits.
+ for line in datasetFile:
+ trait_line = webqtlUtil.readLineCSV(line)
+ trait_name = trait_line[0]
+ trait_data = trait_line[1:]
+
+ if useLit:
+ if not litCorrs.has_key( trait_name ):
+ continue
+
+ if useTissueCorr:
+ if not tissueCorrs.has_key( trait_name ):
+ continue
+
+ #XZ, 04/01/2010: If useLit or useTissueCorr, and this trait should not be added,
+ #it will not go to the next step.
+
+ good_dataset_vals = []
+ for i in good_dataset_strains_index:
+ if i == -99999:
+ good_dataset_vals.append(None)
+ else:
+ good_dataset_vals.append( float(trait_data[i]) )
+
+ allTargetTraitNames.append(trait_name)
+ allTargetTraitValues.append(good_dataset_vals)
+
+ datasetFile.close()
+
+ if self.method in ["2", "5"]: #Spearman
+ allcorrelations = correlationFunction.determinePartialsByR(primaryVal=_vals, controlVals=_controlvals, targetVals=allTargetTraitValues, targetNames=allTargetTraitNames, method='s')
+ else:
+ allcorrelations = correlationFunction.determinePartialsByR(primaryVal=_vals, controlVals=_controlvals, targetVals=allTargetTraitValues, targetNames=allTargetTraitNames)
+
+ totalTraits = len(allcorrelations)
+
+ if useLit or useTissueCorr:
+ for i, item in enumerate(allcorrelations):
+ if useLit:
+ allcorrelations[i].append(litCorrs[ item[0] ])
+ if useTissueCorr:
+ tempCorr, tempPValue = tissueCorrs[ item[0] ]
+ allcorrelations[i].append(tempCorr)
+ allcorrelations[i].append(tempPValue)
+
+ return totalTraits, allcorrelations
+ except:
+ return 0, 0
+
+
+ def getPartialCorrelationsNormal(self, _strains, _vals, _controlvals, nnCorr, species, input_trait_GeneId, input_trait_symbol,TissueProbeSetFreezeId):
+ """Calculates and returns correlation coefficients"""
+
+ traitdatabase, dataStartPos = self.fetchAllDatabaseData(species=species, GeneId=input_trait_GeneId, GeneSymbol=input_trait_symbol, strains=_strains, db=self.db, method=self.method, returnNumber=self.returnNumber, tissueProbeSetFreezeId=TissueProbeSetFreezeId)
+ totalTraits = len(traitdatabase) #XZ, 09/18/2008: total trait number
+
+ allcorrelations = []
+
+ allTargetTraitNames = []
+ allTargetTraitValues = []
+
+ for traitdata in traitdatabase:
+ traitdataName = traitdata[0]
+ traitvals = traitdata[dataStartPos:]
+ allTargetTraitNames.append (traitdataName)
+ allTargetTraitValues.append (traitvals)
+
+ if self.method in ["2", "5"]: #Spearman
+ allcorrelations = correlationFunction.determinePartialsByR(primaryVal=_vals, controlVals=_controlvals, targetVals=allTargetTraitValues, targetNames=allTargetTraitNames, method='s')
+ else:
+ allcorrelations = correlationFunction.determinePartialsByR(primaryVal=_vals, controlVals=_controlvals, targetVals=allTargetTraitValues, targetNames=allTargetTraitNames)
+
+ #XZ, 09/28/2008: if user select '3', then fetchAllDatabaseData would give us LitCorr in the [1] position
+ #XZ, 09/28/2008: if user select '4' or '5', then fetchAllDatabaseData would give us Tissue Corr in the [1] position
+ #XZ, 09/28/2008: and Tissue Corr P Value in the [2] position
+ if input_trait_GeneId and self.db.type == "ProbeSet" and self.method in ["3", "4", "5"]:
+ for i, item in enumerate(allcorrelations):
+ if self.method == "3":
+ item.append( traitdatabase[1] )
+ if self.method == "4" or self.method == "5":
+ item.append( traitdatabase[1] )
+ item.append( traitdatabase[2] )
+
+
+ return totalTraits, allcorrelations
+
+
+ def getTableHeaderForPublish(self, method=None, worksheet=None, newrow=None, headingStyle=None):
+
+ tblobj_header = []
+
+ if method in ["1", "3", "4"]:
+ tblobj_header = [[THCell(HT.TD('', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), sort=0),
+ THCell(HT.TD('Record', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="id", idx=1),
+ THCell(HT.TD('Phenotype', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="pheno", idx=2),
+ THCell(HT.TD('Authors', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="auth", idx=3),
+ THCell(HT.TD('Year', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="year", idx=4),
+ THCell(HT.TD('N', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="nstr", idx=5),
+ THCell(HT.TD('Partial r ', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="partial_corr", idx=6),
+ THCell(HT.TD('p(partial r)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="partial_pv", idx=7),
+ THCell(HT.TD('r ', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="corr", idx=8),
+ THCell(HT.TD('p(r)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="pv", idx=9),
+ THCell(HT.TD('delta r', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="delta_corr", idx=10)]]
+
+ for ncol, item in enumerate(["Record", "Phenotype", "Authors", "Year", "PubMedID", "N", "Partial r", "p(partial r)", "r ", "p(r)", "delta r"]):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+ else:
+ tblobj_header = [[THCell(HT.TD('', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), sort=0),
+ THCell(HT.TD('Record', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="id", idx=1),
+ THCell(HT.TD('Phenotype', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="pheno", idx=2),
+ THCell(HT.TD('Authors', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="auth", idx=3),
+ THCell(HT.TD('Year', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="year", idx=4),
+ THCell(HT.TD('N', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="nstr", idx=5),
+ THCell(HT.TD('Partial rho ', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="partial_corr", idx=6),
+ THCell(HT.TD('p(partial rho)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="partial_pv", idx=7),
+ THCell(HT.TD('rho ', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="corr", idx=8),
+ THCell(HT.TD('p(rho)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="pv", idx=9),
+ THCell(HT.TD('delta rho', Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="delta_corr", idx=10)]]
+
+ for ncol, item in enumerate(["Record", "Phenotype", "Authors", "Year", "PubMedID", "N", "Partial rho", "p(partial rho)", "rho ", "p(rho)", "delta rho"]):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+ return tblobj_header, worksheet
+
+
+ def getTableBodyForPublish(self, traitList, formName=None, worksheet=None, newrow=None, corrScript=None):
+
+ tblobj_body = []
+
+ for thisTrait in traitList:
+ tr = []
+
+ trId = str(thisTrait)
+
+ #partial corr value could be string 'NA'
+ try:
+ corrScript.append('corrArray["%s"] = {corr:%1.4f};' % (trId, thisTrait.partial_corr))
+ except:
+ corrScript.append('corrArray["%s"] = {corr:"NA"};' % (trId))
+
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showTrait('%s', '%s')" % (formName, thisTrait.name), Class="fs12 fwn"), nowrap="yes",align="center", Class="fs12 fwn b1 c222"),str(thisTrait.name), thisTrait.name))
+
+ 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
+ tr.append(TDCell(HT.TD(PhenotypeString, Class="fs12 fwn b1 c222"), PhenotypeString, PhenotypeString.upper()))
+
+ tr.append(TDCell(HT.TD(thisTrait.authors, Class="fs12 fwn b1 c222 fsI"),thisTrait.authors, thisTrait.authors.strip().upper()))
+
+ try:
+ PubMedLinkText = myear = repr = int(thisTrait.year)
+ except:
+ PubMedLinkText = repr = "N/A"
+ myear = 0
+ if thisTrait.pubmed_id:
+ PubMedLink = HT.Href(text= repr,url= webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id,target='_blank', Class="fs12 fwn")
+ else:
+ PubMedLink = repr
+
+ tr.append(TDCell(HT.TD(PubMedLink, Class="fs12 fwn b1 c222", align='center'), repr, myear))
+
+ repr = '%d' % thisTrait.NOverlap
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.NOverlap))
+
+ try:
+ repr = '%3.3f' % thisTrait.partial_corr
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn b1 c222", align='right', nowrap="on"), repr, abs(thisTrait.partial_corr)))
+ except:
+ repr = 'NA'
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='left'), text=repr, val=0 ))
+
+ repr = webqtlUtil.SciFloat(thisTrait.partial_corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.partial_corrPValue))
+
+ repr = '%3.3f' % thisTrait.corr
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn b1 c222", align='right', nowrap="on"), repr, abs(thisTrait.corr)))
+
+ repr = webqtlUtil.SciFloat(thisTrait.corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.corrPValue))
+
+ #delta
+ try:
+ delta = '%3.3f' % ( float(thisTrait.partial_corr) - float(thisTrait.corr) )
+ tr.append(TDCell(HT.TD(delta, Class="fs12 fwn ffl b1 c222", align='right', nowrap="on"), text=delta, val=abs(float(delta)) ))
+ except:
+ delta = 'NA'
+ tr.append(TDCell(HT.TD(delta, Class="fs12 fwn ffl b1 c222", align='left'), text=delta, val=0 ))
+
+ tblobj_body.append(tr)
+
+ for ncol, item in enumerate([thisTrait.name, PhenotypeString, thisTrait.authors, thisTrait.year, thisTrait.pubmed_id, thisTrait.NOverlap, thisTrait.partial_corr, thisTrait.partial_corrPValue, thisTrait.corr, thisTrait.corrPValue, delta]):
+ worksheet.write([newrow, ncol], str(item) )
+ newrow += 1
+
+ return tblobj_body, worksheet, corrScript
+
+
+ def getTableHeaderForGeno(self, method=None, worksheet=None, newrow=None, headingStyle=None):
+ tblobj_header = []
+
+ if method in ["1", "3", "4"]:
+ tblobj_header = [[THCell(HT.TD('', Class="fs13 fwb ffl b1 cw cbrb"), sort=0),
+ THCell(HT.TD('Locus', Class="fs13 fwb ffl b1 cw cbrb",align='center'), text='locus', idx=1),
+ THCell(HT.TD('Chr', Class="fs13 fwb ffl b1 cw cbrb"), text='chr', idx=2),
+ THCell(HT.TD('Megabase', Class="fs13 fwb ffl b1 cw cbrb"), text='Mb', idx=3),
+ THCell(HT.TD('N', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='nstr', idx=4),
+ THCell(HT.TD('Partial r ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='partial_corr', idx=5),
+ THCell(HT.TD('p(partial r)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='partial_pv', idx=6),
+ THCell(HT.TD('r ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='corr', idx=7),
+ THCell(HT.TD('p(r)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='pv', idx=8),
+ THCell(HT.TD('delta r', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='delta_corr', idx=9)]]
+
+ for ncol, item in enumerate(['Locus', 'Chr', ' Mb ', ' N ', 'Partial r', 'p(partial r)', 'r ', 'p(r)', 'delta r' ]):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+ else:
+ tblobj_header = [[THCell(HT.TD('', Class="fs13 fwb ffl b1 cw cbrb"), sort=0),
+ THCell(HT.TD('Locus', Class="fs13 fwb ffl b1 cw cbrb",align='center'), text='locus', idx=1),
+ THCell(HT.TD('Chr', Class="fs13 fwb ffl b1 cw cbrb"), text='chr', idx=2),
+ THCell(HT.TD('Megabase', Class="fs13 fwb ffl b1 cw cbrb"), text='Mb', idx=3),
+ THCell(HT.TD('N', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='nstr', idx=4),
+ THCell(HT.TD('Partial rho', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='partial_corr', idx=5),
+ THCell(HT.TD('p(partial rho)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='partial_pv', idx=6),
+ THCell(HT.TD('rho ', Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text='corr', idx=7),
+ THCell(HT.TD('p(rho)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='pv', idx=8),
+ THCell(HT.TD('delta rho', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='delta_corr', idx=9)]]
+
+ for ncol, item in enumerate(['Locus', 'Chr', ' Mb ', ' N ', 'Partial rho', 'p(partial rho)', 'rho ', 'p(rho)', 'delta rho' ]):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+ return tblobj_header, worksheet
+
+
+
+ def getTableBodyForGeno(self, traitList, formName=None, worksheet=None, newrow=None, corrScript=None):
+
+ tblobj_body = []
+
+ for thisTrait in traitList:
+ tr = []
+
+ trId = str(thisTrait)
+
+ #partial corr value could be string 'NA'
+ try:
+ corrScript.append('corrArray["%s"] = {corr:%1.4f};' % (trId, thisTrait.partial_corr))
+ except:
+ corrScript.append('corrArray["%s"] = {corr:"NA"};' % (trId))
+
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showTrait('%s', '%s')" % (formName, thisTrait.name), Class="fs12 fwn ffl"),align="center", Class="fs12 fwn ffl b1 c222"), text=thisTrait.name, val=thisTrait.name.upper()))
+
+ #tr.append(TDCell(HT.TD(thisTrait.chr, Class="fs12 fwn ffl b1 c222", align='right'), text=str(thisTrait.chr)))
+
+ try:
+ Mbvalue = int(thisTrait.chr)*1000 + thisTrait.mb
+ except:
+ if not thisTrait.chr or not thisTrait.mb:
+ Mbvalue = 1000000
+ elif thisTrait.chr.upper() == 'X':
+ Mbvalue = 20*1000 + thisTrait.mb
+ else:
+ Mbvalue = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb
+
+ tr.append(TDCell( HT.TD(thisTrait.chr, Class="fs12 fwn b1 c222", align='right'), thisTrait.chr, Mbvalue) )
+ tr.append(TDCell(HT.TD(thisTrait.mb, Class="fs12 fwn ffl b1 c222", align='right'), text=str(thisTrait.mb), val=Mbvalue))
+
+ repr = '%d' % thisTrait.NOverlap
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.NOverlap))
+
+ try:
+ repr='%3.3f' % thisTrait.partial_corr
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right',nowrap='ON'),repr,abs(thisTrait.partial_corr)))
+ except:
+ repr = 'NA'
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='left'), text=repr, val=0 ))
+
+ repr = webqtlUtil.SciFloat(thisTrait.partial_corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.partial_corrPValue))
+
+ repr = '%3.3f' % thisTrait.corr
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn b1 c222", align='right',nowrap='ON'), repr, abs(thisTrait.corr)))
+
+ repr = webqtlUtil.SciFloat(thisTrait.corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.corrPValue))
+
+ #delta
+ try:
+ delta = '%3.3f' % ( float(thisTrait.partial_corr) - float(thisTrait.corr) )
+ tr.append(TDCell(HT.TD(delta, Class="fs12 fwn ffl b1 c222", align='right', nowrap='ON'), text=delta, val=abs(float(delta)) ))
+ except:
+ delta = 'NA'
+ tr.append(TDCell(HT.TD(delta, Class="fs12 fwn ffl b1 c222", align='left'), text=delta, val=0 ))
+
+ tblobj_body.append(tr)
+
+ for ncol, item in enumerate([thisTrait.name, thisTrait.chr, thisTrait.mb, thisTrait.NOverlap, thisTrait.partial_corr, thisTrait.partial_corrPValue, thisTrait.corr, thisTrait.corrPValue, delta]):
+ worksheet.write([newrow, ncol], item)
+ newrow += 1
+
+ return tblobj_body, worksheet, corrScript
+
+
+ def getTableHeaderForProbeSet(self, method=None, worksheet=None, newrow=None, headingStyle=None):
+
+ tblobj_header = []
+
+ if method in ["1","3","4"]:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0),
+ THCell(HT.TD('Record',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="id", idx=1),
+ THCell(HT.TD('','Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="symbol", idx=2),
+ THCell(HT.TD('','Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="desc", idx=3),
+ #XZ, 12/09/2008: sort chr
+ THCell(HT.TD('','Chr',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="chr", idx=4),
+ THCell(HT.TD('','Mb',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Mb", idx=5),
+ THCell(HT.TD('Mean',HT.BR(),'Expr',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="mean", idx=6),
+ THCell(HT.TD('N',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="nstr", idx=7),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'Partial r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="partial_corr", idx=8),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(partial r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="partial_pv", idx=9),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="corr", idx=10),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="pv", idx=11),
+ THCell(HT.TD('delta',HT.BR(), 'r', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="delta_corr", idx=12),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Pubmed',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#literatureCorr"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="lcorr", idx=13),
+ #XZ, 09/22/2008: tissue correlation
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuecorr", idx=14),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'p(r)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuepvalue", idx=15)]]
+
+ for ncol, item in enumerate(['Record', 'Gene ID', 'Symbol', 'Description', 'Chr', 'Megabase', 'Mean Expr', 'N ', 'Sample Partial r', 'Sample p(partial r)', 'Sample r', 'Sample p(r)', 'delta r', 'Lit Corr', 'Tissue r', 'Tissue p(r)']):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+ else:
+ tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0),
+ THCell(HT.TD('Record',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="id", idx=1),
+ THCell(HT.TD('','Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="symbol", idx=2),
+ THCell(HT.TD('','Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="desc", idx=3),
+ THCell(HT.TD('','Chr',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="chr", idx=4),
+ THCell(HT.TD('','Mb',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="Mb", idx=5),
+ THCell(HT.TD('Mean',HT.BR(),'Expr',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="mean", idx=6),
+ THCell(HT.TD('N',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="nstr", idx=7),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'Partial rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="partial_corr", idx=8),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(partial rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="partial_pv", idx=9),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="corr", idx=10),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Sample',HT.BR(), 'p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#genetic_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="pv", idx=11),
+ THCell(HT.TD('delta',HT.BR(),'rho', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="delta_corr", idx=12),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Pubmed',HT.BR(), 'r', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#literatureCorr"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="lcorr", idx=13),
+ #XZ, 09/22/2008: tissue correlation
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'rho', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuecorr", idx=14),
+ THCell(HT.TD(HT.Href(
+ text = HT.Span('Tissue',HT.BR(), 'p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_p_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuepvalue", idx=15)]]
+
+ for ncol, item in enumerate(['Record', 'Gene ID', 'Symbol', 'Description', 'Chr', 'Megabase', 'Mean Expr', 'N ', 'Sample Partial rho', 'Sample p(partial rho)', 'Sample rho', 'Sample p(rho)', 'delta rho', 'Pubmed r', 'Tissue rho', 'Tissue p(rho)']):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+ return tblobj_header, worksheet
+
+
+ def getTableBodyForProbeSet(self, traitList=[], primaryTrait=None, formName=None, worksheet=None, newrow=None, corrScript=None):
+
+ tblobj_body = []
+
+ for thisTrait in traitList:
+
+ if thisTrait.symbol:
+ pass
+ else:
+ thisTrait.symbol = "N/A"
+
+ 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="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="fs12 fwn")
+
+ tr = []
+
+ trId = str(thisTrait)
+
+ #partial corr value could be string 'NA'
+ try:
+ corrScript.append('corrArray["%s"] = {corr:%1.4f};' % (trId, thisTrait.partial_corr))
+ except:
+ corrScript.append('corrArray["%s"] = {corr:"NA"};' % (trId))
+
+ #XZ, 12/08/2008: checkbox
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+
+ #XZ, 12/08/2008: probeset name
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showTrait('%s', '%s')" % (formName,thisTrait.name), Class="fs12 fwn"), Class="fs12 fwn b1 c222"), thisTrait.name, thisTrait.name.upper()))
+
+ #XZ, 12/08/2008: gene symbol
+ tr.append(TDCell(HT.TD(symbolurl, Class="fs12 fwn b1 c222 fsI"),thisTrait.symbol, thisTrait.symbol.upper()))
+
+ #XZ, 12/08/2008: description
+ #XZ, 06/05/2009: Rob asked to add probe target description
+ description_string = str(thisTrait.description).strip()
+ 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()
+
+ tr.append(TDCell(HT.TD(description_display, Class="fs12 fwn b1 c222"), description_display, description_display))
+
+ #XZ, 12/08/2008: Mbvalue is used for sorting
+ try:
+ Mbvalue = int(thisTrait.chr)*1000 + thisTrait.mb
+ except:
+ if not thisTrait.chr or not thisTrait.mb:
+ Mbvalue = 1000000
+ elif thisTrait.chr.upper() == 'X':
+ Mbvalue = 20*1000 + thisTrait.mb
+ else:
+ Mbvalue = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb
+
+ #XZ, 12/08/2008: chromosome number
+ #XZ, 12/10/2008: use Mbvalue to sort chromosome
+ tr.append(TDCell( HT.TD(thisTrait.chr, Class="fs12 fwn b1 c222", align='right'), thisTrait.chr, Mbvalue) )
+
+ #XZ, 12/08/2008: Rob wants 6 digit precision, and we have to deal with that the mb could be None
+ if not thisTrait.mb:
+ tr.append(TDCell(HT.TD(thisTrait.mb, Class="fs12 fwn b1 c222",align='right'), thisTrait.mb, Mbvalue))
+ else:
+ tr.append(TDCell(HT.TD('%.6f' % thisTrait.mb, Class="fs12 fwn b1 c222", align='right'), thisTrait.mb, Mbvalue))
+
+ #XZ, 01/12/08: This SQL query is much faster.
+ 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="fs12 fwn ffl b1 c222", align='right', nowrap='ON'),repr, mean))
+
+ #XZ: number of overlaped cases for partial corr
+ repr = '%d' % thisTrait.NOverlap
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.NOverlap))
+
+ #XZ: sample partial correlation
+ try:
+ repr='%3.3f' % thisTrait.partial_corr
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right', nowrap='ON'),repr,abs(thisTrait.partial_corr)))
+ except:
+ repr = 'NA'
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='left'), text=repr, val=0 ))
+
+ #XZ: p value of genetic partial correlation
+ repr = webqtlUtil.SciFloat(thisTrait.partial_corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.partial_corrPValue))
+
+ repr = '%3.3f' % thisTrait.corr
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn b1 c222", align='right',nowrap='ON'), repr, abs(thisTrait.corr)))
+
+ repr = webqtlUtil.SciFloat(thisTrait.corrPValue)
+ tr.append(TDCell(HT.TD(repr,nowrap='ON', Class="fs12 fwn ffl b1 c222", align='right'),repr,thisTrait.corrPValue))
+
+ #delta
+ try:
+ delta = '%3.3f' % ( float(thisTrait.partial_corr) - float(thisTrait.corr) )
+ tr.append(TDCell(HT.TD(delta, Class="fs12 fwn ffl b1 c222", align='right', nowrap='ON'), text=delta, val=abs(float(delta)) ))
+ except:
+ delta = 'NA'
+ tr.append(TDCell(HT.TD(delta, Class="fs12 fwn ffl b1 c222", align='left'), text=delta, val=0 ))
+
+ #XZ, 12/08/2008: literature correlation
+ LCorr = 0.0
+ LCorrStr = "N/A"
+ if hasattr(thisTrait, 'LCorr') and thisTrait.LCorr:
+ LCorr = thisTrait.LCorr
+ LCorrStr = "%2.3f" % thisTrait.LCorr
+ tr.append(TDCell(HT.TD(LCorrStr, Class="fs12 fwn b1 c222", align='right'), LCorrStr, abs(LCorr)))
+
+ #XZ, 09/22/2008: tissue correlation.
+ TCorr = 0.0
+ TCorrStr = "N/A"
+ #XZ, 11/18/2010: need to pass two gene symbols
+ if hasattr(thisTrait, 'tissueCorr') and thisTrait.tissueCorr:
+ TCorr = thisTrait.tissueCorr
+ TCorrStr = "%2.3f" % thisTrait.tissueCorr
+ #NL, 07/19/2010: add a new parameter rankOrder for js function 'showTissueCorrPlot'
+ rankOrder =thisTrait.rankOrder
+ TCorrPlotURL = "javascript:showTissueCorrPlot('%s','%s','%s',%d)" %(formName, primaryTrait.symbol, thisTrait.symbol,rankOrder)
+ tr.append(TDCell(HT.TD(HT.Href(text=TCorrStr, url=TCorrPlotURL, Class="fs12 fwn ff1"), Class="fs12 fwn ff1 b1 c222", align='right'), TCorrStr, abs(TCorr) ))
+ else:
+ tr.append(TDCell(HT.TD(TCorrStr, Class="fs12 fwn b1 c222", align='right'), TCorrStr, abs(TCorr)))
+
+ #XZ, 12/08/2008: p value of tissue correlation
+ TPValue = 1.0
+ TPValueStr = "N/A"
+ if hasattr(thisTrait, 'tissueCorr') and thisTrait.tissueCorr: #XZ, 09/22/2008: thisTrait.tissuePValue can't be used here because it could be 0
+ TPValue = thisTrait.tissuePValue
+ TPValueStr = "%2.3f" % thisTrait.tissuePValue
+ tr.append(TDCell(HT.TD(TPValueStr, Class="fs12 fwn b1 c222", align='right'), TPValueStr, abs(TPValue) ))
+
+ tblobj_body.append(tr)
+
+ for ncol, item in enumerate([thisTrait.name, thisTrait.geneid, thisTrait.symbol, thisTrait.description, thisTrait.chr, thisTrait.mb, mean, thisTrait.NOverlap, thisTrait.partial_corr, thisTrait.partial_corrPValue, thisTrait.corr, thisTrait.corrPValue, delta, LCorrStr, TCorrStr, TPValueStr]):
+ worksheet.write([newrow, ncol], item)
+
+ newrow += 1
+
+ return tblobj_body, worksheet, corrScript
+
+
+ def getFormForPrimaryAndControlTraits (self, primaryTrait, controlTraits):
+
+ info_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', 'database':'_', 'ProbeSetID':'_', 'CellID':'_' }#XZ: These four parameters are required by javascript function showDatabase2.
+
+ for key in hddn.keys():
+ info_form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ info_form.append(HT.Paragraph("Primary Trait", Class="subtitle"), '\n')
+
+ primaryTraitTable = HT.TableLite(cellSpacing=4,cellPadding=0,width="90%",border=0)
+ descriptionString = primaryTrait.genHTML(dispFromDatabase=1)
+ if primaryTrait.db.type == 'Publish' and primaryTrait.confidential:
+ descriptionString = primaryTrait.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=primaryTrait.authorized_users)
+ primaryTraitTable.append(HT.TR(HT.TD(HT.Href(text='%s' % descriptionString, url="javascript:showDatabase2('%s','%s','%s')" % (primaryTrait.db.name,primaryTrait.name,primaryTrait.cellid), Class="fs12 fwn") )))
+
+ info_form.append(primaryTraitTable)
+
+ info_form.append(HT.Paragraph("Control Traits", Class="subtitle"), '\n')
+
+ controlTraitsTable = HT.TableLite(cellSpacing=4,cellPadding=0,width="90%",border=0)
+
+ seq = 1
+
+ ## Generate the listing table for control traits
+ for thisTrait in controlTraits:
+ descriptionString = thisTrait.genHTML(dispFromDatabase=1)
+ if thisTrait.db.type == 'Publish' and thisTrait.confidential:
+ descriptionString = thisTrait.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users)
+ controlTraitsTable.append(HT.TR(HT.TD("%d."%seq,align="right",width=10),
+ HT.TD(HT.Href(text='%s' % descriptionString,url="javascript:showDatabase2('%s','%s','%s')" % (thisTrait.db.name,thisTrait.name,thisTrait.cellid), Class="fs12 fwn") )))
+ seq += 1
+
+ info_form.append(controlTraitsTable)
+
+ return info_form
diff --git a/web/webqtl/correlation/PartialCorrInputPage.py b/web/webqtl/correlation/PartialCorrInputPage.py
new file mode 100755
index 00000000..7d32da6d
--- /dev/null
+++ b/web/webqtl/correlation/PartialCorrInputPage.py
@@ -0,0 +1,484 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+import string
+import cPickle
+
+from htmlgen import HTMLgen2 as HT
+
+from base import webqtlConfig
+from utility.THCell import THCell
+from utility.TDCell import TDCell
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from dbFunction import webqtlDatabaseFunction
+from utility import webqtlUtil
+
+
+
+class PartialCorrInputPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ searchResult = fd.formdata.getvalue('searchResult')
+
+ if not searchResult:
+ heading = 'Partial Correlation'
+ detail = ['You need to select at least three traits in order to calculate partial correlation.']
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ ## Adds the Trait instance for each trait name from the collection
+ traits = []
+
+ for item in searchResult:
+ traits.append(webqtlTrait(fullname=item, cursor=self.cursor))
+
+ RISet = fd.formdata.getvalue('RISet')
+ species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet)
+
+ #XZ: HTML part
+ TD_LR = HT.TD(colspan=2,height=200,width="100%",bgColor='#eeeeee')
+ TD_LR.append("Please select one primary trait, one to three control traits, and at least one target trait.", HT.P() )
+
+ mainFormName = 'showDatabase'
+ mainForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name=mainFormName,submit=HT.Input(type='hidden'))
+
+ #XZ: Add hidden form values
+ hddn = {'FormID':'calPartialCorrTrait', 'database':'', 'ProbeSetID':'', 'CellID':'', #XZ: These four parameters are required by javascript function showDatabase2.
+ 'controlTraits':'',
+ 'primaryTrait':'',
+ 'targetTraits':'',
+ 'pcMethod':'',
+ 'RISet':RISet
+ }
+
+
+ for key in hddn.keys():
+ mainForm.append(HT.Input(type='hidden', name=key, value=hddn[key]))
+
+ radioNames = []
+
+ for thisTrait in traits:
+ oneRadioName = thisTrait.getName()
+ radioNames.append(oneRadioName)
+
+ radioNamesString = ','.join(radioNames)
+
+ # Creates the image href that runs the javascript setting all traits as target or ignored
+ setAllTarget = HT.Href(url="#redirect", onClick="setAllAsTarget(document.getElementsByName('showDatabase')[0], '%s');" % radioNamesString)
+ setAllTargetImg = HT.Image("/images/select_all.gif", alt="Select All", title="Select All", style="border:none;")
+ setAllTarget.append(setAllTargetImg)
+ setAllIgnore = HT.Href(url="#redirect", onClick="setAllAsIgnore(document.getElementsByName('showDatabase')[0], '%s');" % radioNamesString)
+ setAllIgnoreImg = HT.Image("/images/select_all.gif", alt="Select All", title="Select All", style="border:none;")
+ setAllIgnore.append(setAllIgnoreImg)
+
+
+ tblobj = {}
+ tblobj['header'] = self.getCollectionTableHeader()
+
+ sortby = self.getSortByValue()
+
+ tblobj['body'] = self.getCollectionTableBody(traitList=traits, formName=mainFormName, species=species)
+
+ filename= webqtlUtil.genRandStr("Search_")
+
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "1"), Id="sortable")
+
+ mainForm.append(div)
+
+ #XZ: Add button
+ radioNamesString = ','.join(radioNames)
+ jsCommand_1 = "validateTrait(this.form, \'" + radioNamesString + "\', 0, 1);"
+ jsCommand_2 = "validateTrait(this.form, \'" + radioNamesString + "\', 0, 2);"
+ partialCorrTraitButton_1 = HT.Input(type='button', name='submitPartialCorrTrait_1', value='Pearson\'s r', onClick='%s' % jsCommand_1, Class="button")
+ partialCorrTraitButton_2 = HT.Input(type='button', name='submitPartialCorrTrait_2', value='Spearman\'s rho', onClick='%s' % jsCommand_2, Class="button")
+ mainForm.append(HT.BR(), "Compute partial correlation for target selected above:", HT.BR(), partialCorrTraitButton_1, partialCorrTraitButton_2, HT.BR(), HT.BR(), HT.HR(color="gray",size=3) )
+
+ jsCommand = "validateTrait(this.form, \'" + radioNamesString + "\', 1);"
+ partialCorrDBButton = HT.Input(type='button', name='submitPartialCorrDB', value='Calculate', onClick='%s' % jsCommand,Class="button")
+
+ methodText = HT.Span("Calculate:", Class="ffl fwb fs12")
+
+ methodMenu = HT.Select(name='method')
+ methodMenu.append(('Genetic Correlation, Pearson\'s r','1'))
+ methodMenu.append(('Genetic Correlation, Spearman\'s rho','2'))
+ methodMenu.append(('SGO Literature Correlation','3'))
+ methodMenu.append(('Tissue Correlation, Pearson\'s r','4'))
+ methodMenu.append(('Tissue Correlation, Spearman\'s rho','5'))
+
+ databaseText = HT.Span("Choose Database:", Class="ffl fwb fs12")
+ databaseMenu = HT.Select(name='database2')
+
+ nmenu = 0
+
+ self.cursor.execute('SELECT PublishFreeze.FullName,PublishFreeze.Name FROM \
+ PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id \
+ and InbredSet.Name = "%s" and PublishFreeze.public > %d' % \
+ (RISet,webqtlConfig.PUBLICTHRESH))
+ for item in self.cursor.fetchall():
+ databaseMenu.append(item)
+ nmenu += 1
+
+ self.cursor.execute('SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze,\
+ InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = \
+ "%s" and GenoFreeze.public > %d' % (RISet,webqtlConfig.PUBLICTHRESH))
+ for item in self.cursor.fetchall():
+ databaseMenu.append(item)
+ nmenu += 1
+
+ #03/09/2009: Xiaodong changed the SQL query to order by Name as requested by Rob.
+ self.cursor.execute('SELECT Id, Name FROM Tissue order by Name')
+ for item in self.cursor.fetchall():
+ TId, TName = item
+ databaseMenuSub = HT.Optgroup(label = '%s ------' % TName)
+ self.cursor.execute('SELECT ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, \
+ InbredSet WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = %d and \
+ ProbeSetFreeze.public > %d and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like "%s%%" \
+ order by ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId ' % (TId,webqtlConfig.PUBLICTHRESH, RISet))
+ for item2 in self.cursor.fetchall():
+ databaseMenuSub.append(item2)
+ nmenu += 1
+ databaseMenu.append(databaseMenuSub)
+
+ if nmenu:
+ criteriaText = HT.Span("Return:", Class="ffl fwb fs12")
+ criteriaMenu = HT.Select(name='criteria', selected='500')
+ criteriaMenu.append(('top 100','100'))
+ criteriaMenu.append(('top 200','200'))
+ criteriaMenu.append(('top 500','500'))
+ criteriaMenu.append(('top 1000','1000'))
+ criteriaMenu.append(('top 2000','2000'))
+ criteriaMenu.append(('top 5000','5000'))
+ criteriaMenu.append(('top 10000','10000'))
+ criteriaMenu.append(('top 15000','15000'))
+ criteriaMenu.append(('top 20000','20000'))
+
+ self.MPDCell = HT.TD()
+ correlationMenus = HT.TableLite(
+ HT.TR(
+ HT.TD(databaseText,HT.BR(),databaseMenu, colspan=4)
+ ),
+ HT.TR(
+ HT.TD(methodText,HT.BR(),methodMenu),
+ self.MPDCell,
+ HT.TD(criteriaText,HT.BR(),criteriaMenu)),
+ border=0, cellspacing=4, cellpadding=0)
+ else:
+ correlationMenus = ""
+
+ mainForm.append(HT.Font('or',color='red', size=4), HT.BR(), HT.BR(), "Compute partial correlation for each trait in the database selected below:", HT.BR() )
+ mainForm.append( partialCorrDBButton, HT.BR(), HT.BR(), correlationMenus)
+
+ TD_LR.append(mainForm)
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['js1'] =''
+ self.dict['title'] = 'Partial Correlation Input'
+
+
+ def getCollectionTableHeader(self):
+
+ tblobj_header = []
+
+ className = "fs13 fwb ffl b1 cw cbrb"
+
+ tblobj_header = [[THCell(HT.TD('Index', Class=className, nowrap="on"), sort=0),
+ THCell(HT.TD("Primary (X)",align="center", Class="fs13 fwb ffl b1 cw cbrb", nowrap="ON"), text="primary", sort=0),
+ THCell(HT.TD("Control (Z)",align="center", Class="fs13 fwb ffl b1 cw cbrb", nowrap="ON"), text="control", sort=0),
+ THCell(HT.TD("Target (Y)",align="center", Class="fs13 fwb ffl b1 cw cbrb", nowrap="ON"), text="target", sort=0),
+ THCell(HT.TD("Ignored",align="center", Class="fs13 fwb ffl b1 cw cbrb", nowrap="ON"), text="target", sort=0),
+ THCell(HT.TD('Dataset', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="dataset", idx=1),
+ THCell(HT.TD('Trait', HT.BR(), 'ID', HT.BR(), valign="top", Class=className, nowrap="on"), text="name", idx=2),
+ THCell(HT.TD('Description', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="desc", idx=3),
+ THCell(HT.TD('Location', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="location", idx=4),
+ THCell(HT.TD('Mean', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="mean", idx=5),
+ THCell(HT.TD('N', HT.BR(), 'Cases', HT.BR(), valign="top", Class=className, nowrap="on"), text="samples", idx=6),
+ THCell(HT.TD('Max LRS', HT.BR(), HT.BR(), valign="top", Class=className, nowrap="on"), text="lrs", idx=7),
+ THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb', HT.BR(), valign="top", Class=className, nowrap="on"), text="lrs_location", idx=8)]]
+
+ return tblobj_header
+
+
+
+ def getCollectionTableBody(self, 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)
+
+ trId = str(thisTrait)
+
+ oneRadioName = thisTrait.getName()
+
+ tr.append(TDCell( HT.TD(' ',align="center",valign="center",Class=className) ))
+ tr.append(TDCell( HT.TD(HT.Input(type="radio", name=oneRadioName, value="primary"),align="center",valign="center",Class=className) ))
+ tr.append(TDCell( HT.TD(HT.Input(type="radio", name=oneRadioName, value="control"),align="center",valign="center",Class=className) ))
+ tr.append(TDCell( HT.TD(HT.Input(type="radio", name=oneRadioName, value="target", checked="true"),align="center",valign="center",Class=className) ))
+ tr.append(TDCell( HT.TD(HT.Input(type="radio", name=oneRadioName, value="ignored"),align="center",valign="center",Class=className) ))
+
+ tr.append(TDCell(HT.TD(thisTrait.db.name, Class="fs12 fwn b1 c222"), thisTrait.db.name, thisTrait.db.name.upper()))
+
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,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))
+
+ #description column
+ if (thisTrait.db.type == "Publish"):
+ 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
+ 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"):
+ 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
+
+ tr.append(TDCell(HT.TD(description_string, Class=className), description_string, description_string))
+ else:
+ tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
+
+ #location column
+ if (thisTrait.db.type == "Publish"):
+ tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
+ else:
+ #ZS: trait_location_value is used for sorting
+ trait_location_repr = "N/A"
+ 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="yes", Class=className), trait_location_repr, trait_location_value) )
+
+ if (thisTrait.db.type == "ProbeSet"):
+ 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))
+
+
+ if (thisTrait.db.type != "Geno"):
+ #LRS and its location
+ LRS_score_repr = '--'
+ LRS_score_value = 0
+ 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_score_repr = '%3.1f' % thisTrait.lrs
+ LRS_score_value = thisTrait.lrs
+ LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) )
+ LRS_flag = 0
+
+ tr.append(TDCell(HT.TD(LRS_score_repr, Class=className, align='right', nowrap="on"), LRS_score_repr, LRS_score_value))
+ 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_score_repr, Class=className), LRS_score_repr, LRS_score_value))
+ 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))
+
+ tblobj_body.append(tr)
+
+ return tblobj_body
+
+
+
+ def getSortByValue(self):
+
+ sortby = ("pv", "up")
+
+ return sortby
+
diff --git a/web/webqtl/correlation/PartialCorrTraitPage.py b/web/webqtl/correlation/PartialCorrTraitPage.py
new file mode 100755
index 00000000..1c79e250
--- /dev/null
+++ b/web/webqtl/correlation/PartialCorrTraitPage.py
@@ -0,0 +1,310 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import string
+import cPickle
+import os
+
+from htmlgen import HTMLgen2 as HT
+
+from base import webqtlConfig
+from utility.THCell import THCell
+from utility.TDCell import TDCell
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from CorrelationPage import CorrelationPage
+import correlationFunction
+
+
+
+class PartialCorrTraitPage(CorrelationPage):
+
+ corrMinInformative = 4
+
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ TD_LR = HT.TD(colspan=2,height=200,width="100%",bgColor='#eeeeee')
+
+ TD_LR.append(HT.Paragraph("Partial Correlation Table", Class="title"), '\n')
+
+ pc_method = fd.formdata.getvalue('pcMethod')
+
+ primaryTraitString = fd.formdata.getvalue('primaryTrait')
+ primaryTrait = (webqtlTrait(fullname=primaryTraitString, cursor=self.cursor))
+
+ controlTraitsString = fd.formdata.getvalue('controlTraits')
+ controlTraitsList = list(string.split(controlTraitsString,','))
+ controlTraits = []
+ for item in controlTraitsList:
+ controlTraits.append(webqtlTrait(fullname=item, cursor=self.cursor))
+
+ targetTraitsString = fd.formdata.getvalue('targetTraits')
+ targetTraitsList = list(string.split(targetTraitsString,','))
+ targetTraits = []
+ _targetnames = []
+ for item in targetTraitsList:
+ oneTargetTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ oneTargetTrait.retrieveInfo()
+ targetTraits.append( oneTargetTrait )
+ _targetnames.append( oneTargetTrait.name )
+
+ #XZ: filter out the strains that have no value.
+ primaryTrait.retrieveData()
+ _strains, _vals, _vars = primaryTrait.exportInformative()
+
+ #XZ: _controlstrains, _controlvals and _controlvars are list of list [ [], [], ...]. _controlNs is number
+ _controlstrains,_controlvals,_controlvars,_controlNs = correlationFunction.controlStrains(controlTraitsString,_strains)
+
+ N = len(_strains)
+
+ allsame = True
+ ##allsame is boolean for whether or not primary and control trait have values for the same strains
+ for i in _controlstrains:
+ if _strains != i:
+ allsame=False
+ break
+
+ ## If the strains for which each of the control traits and the primary trait have values are not identical,
+ ## we must remove from the calculation all vlaues for strains that are not present in each. Without doing this,
+ ## undesirable biases would be introduced.
+ # XZ, 01/11/2010: After execution of function fixStrains, variables _vals,_controlvals,_vars,_controlvars have the same number and same order of strains as strains in variable _strains. The _controlstrains remains intact.
+ if not allsame:
+ _strains,_vals,_controlvals,_vars,_controlvars = correlationFunction.fixStrains(_strains,_controlstrains,_vals,_controlvals,_vars,_controlvars)
+ N = len(_strains)
+
+ #XZ: We should check the value of control trait and primary trait here.
+ nameOfIdenticalTraits = correlationFunction.findIdenticalTraits ( _vals, primaryTraitString, _controlvals, controlTraitsList )
+ if nameOfIdenticalTraits:
+ heading = "Partial Correlation Table"
+ detail = ['%s and %s have same values for the %s strains that will be used to calculate partial correlation (common for all primary and control traits). In such case, partial correlation can NOT be calculated. Please re-select your traits.' % (nameOfIdenticalTraits[0], nameOfIdenticalTraits[1], len(_vals))]
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ if N < self.corrMinInformative:
+ heading = "Partial Correlation Table"
+ detail = ['Fewer than %d strain data were entered for %s data set. No calculation of correlation has been attempted.' % (self.corrMinInformative, fd.RISet)]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, 01/11/2010: Pay attention to the target trait strain number and order!
+ #XZ 03/29/2010: need to input target trait values to this function.
+
+ _targetvals = []
+ for oneTargetTrait in targetTraits:
+ oneTargetTrait.retrieveData()
+ oneTraitVals = oneTargetTrait.exportData( _strains )
+ _targetvals.append(oneTraitVals)
+
+
+ if pc_method == 'spearman':
+ allcorrelations = correlationFunction.determinePartialsByR(primaryVal = _vals, controlVals = _controlvals, targetVals = _targetvals, targetNames = _targetnames, method='s')
+ else:
+ allcorrelations = correlationFunction.determinePartialsByR(primaryVal = _vals, controlVals = _controlvals, targetVals = _targetvals, targetNames = _targetnames)
+
+ totalTraits = len(allcorrelations)
+
+
+ info_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', 'database':'_', 'ProbeSetID':'_', 'CellID':'_' }#XZ: These four parameters are required by javascript function showDatabase2.
+
+ for key in hddn.keys():
+ info_form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ info_form.append(HT.Paragraph("Primary Trait", Class="subtitle"), '\n')
+
+ primaryTraitTable = HT.TableLite(cellSpacing=4,cellPadding=0,width="90%",border=0)
+
+ descriptionString = primaryTrait.genHTML(dispFromDatabase=1)
+ if primaryTrait.db.type == 'Publish' and primaryTrait.confidential:
+ descriptionString = primaryTrait.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=primaryTrait.authorized_users)
+ primaryTraitTable.append(HT.TR(HT.TD(HT.Href(text='%s' % descriptionString, url="javascript:showDatabase2('%s','%s','%s')" % (primaryTrait.db.name,primaryTrait.name,primaryTrait.cellid), Class="fs12 fwn") )))
+
+ info_form.append(primaryTraitTable)
+
+ info_form.append(HT.Paragraph("Control Traits", Class="subtitle"), '\n')
+
+ controlTraitsTable = HT.TableLite(cellSpacing=4,cellPadding=0,width="90%",border=0)
+
+ seq = 1
+
+ ## Generate the listing table for control traits
+ for thisTrait in controlTraits:
+ descriptionString = thisTrait.genHTML(dispFromDatabase=1)
+ if thisTrait.db.type == 'Publish' and thisTrait.confidential:
+ descriptionString = thisTrait.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users)
+ controlTraitsTable.append(HT.TR(HT.TD("%d."%seq,align="left", width=10),
+ HT.TD(HT.Href(text='%s' % descriptionString,url="javascript:showDatabase2('%s','%s','%s')" % (thisTrait.db.name,thisTrait.name,thisTrait.cellid), Class="fs12 fwn") )))
+ seq += 1
+
+ info_form.append(controlTraitsTable)
+
+
+ TD_LR.append(info_form)
+
+
+ mainfmName = webqtlUtil.genRandStr("fm_")
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name= mainfmName, submit=HT.Input(type='hidden'))
+
+ hddn = {'FormID':'showDatabase', 'database':'_', 'ProbeSetID':'_', 'CellID':'_' }#XZ: These four parameters are required by javascript function showDatabase2.
+
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+
+ filename= webqtlUtil.genRandStr("Corr_")
+
+ tblobj = {}
+
+ if pc_method == 'spearman':
+ tblobj['header'] = \
+ [[THCell(HT.TD('', Class="fs13 fwb ffl b1 cw cbrb"), sort=0),
+ THCell(HT.TD('Database', Class="fs13 fwb ffl b1 cw cbrb",align='center'), text='db', idx=1),
+ THCell(HT.TD('Record', Class="fs13 fwb ffl b1 cw cbrb",align='center'), text='id', idx=2),
+ THCell(HT.TD('Symbol', Class="fs13 fwb ffl b1 cw cbrb"), text='symbol', idx=3),
+ THCell(HT.TD('Description', Class="fs13 fwb ffl b1 cw cbrb", align='center'), text='desc', idx=4),
+ THCell(HT.TD('N ', nowrap="on", Class="fs13 fwb ffl b1 cw cbrb"), text='nstr', idx=5),
+ THCell(HT.TD('Partial rho ', nowrap="on", Class="fs13 fwb ffl b1 cw cbrb"), text='partial_corr', idx=6),
+ THCell(HT.TD('p(partial rho)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='partial_pv', idx=7),
+ THCell(HT.TD('rho ', nowrap="on", Class="fs13 fwb ffl b1 cw cbrb"), text='corr', idx=8),
+ THCell(HT.TD('p(rho)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='pv', idx=9),
+ THCell(HT.TD('delta rho', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='delta_rho', idx=10)]]
+ else:
+ tblobj['header'] = \
+ [[THCell(HT.TD('', Class="fs13 fwb ffl b1 cw cbrb"), sort=0),
+ THCell(HT.TD('Database', Class="fs13 fwb ffl b1 cw cbrb",align='center'), text='db', idx=1),
+ THCell(HT.TD('Record', Class="fs13 fwb ffl b1 cw cbrb",align='center'), text='id', idx=2),
+ THCell(HT.TD('Symbol', Class="fs13 fwb ffl b1 cw cbrb"), text='symbol', idx=3),
+ THCell(HT.TD('Description', Class="fs13 fwb ffl b1 cw cbrb", align='center'), text='desc', idx=4),
+ THCell(HT.TD('N ', nowrap="on", Class="fs13 fwb ffl b1 cw cbrb"), text='nstr', idx=5),
+ THCell(HT.TD('Partial r ', nowrap="on", Class="fs13 fwb ffl b1 cw cbrb"), text='partial_corr', idx=6),
+ THCell(HT.TD('p(partial r)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='partial_pv', idx=7),
+ THCell(HT.TD('r ', nowrap="on", Class="fs13 fwb ffl b1 cw cbrb"), text='corr', idx=8),
+ THCell(HT.TD('p(r)', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='pv', idx=9),
+ THCell(HT.TD('delta r', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text='delta_r', idx=10)]]
+
+ sortby = ("partial_pv", "up")
+
+ tblobj['body'] = []
+ for i, thisTrait in enumerate(targetTraits):
+ tr = []
+
+ trId = str(thisTrait)
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId))
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.db.fullname,url=webqtlConfig.INFOPAGEHREF % thisTrait.db.name,target="_blank", Class="fs12 fwn"), Class="fs12 fwn ffl b1 c222"), text=thisTrait.db.name, val=thisTrait
+.db.name.upper()))
+ tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showDatabase3('%s', '%s', '%s', '%s')" % (mainfmName,thisTrait.db.name,thisTrait.name,thisTrait.cellid), Class="fs12 fwn"), Class="fs12 fwn b1 c222"), text=thisTrait.name, val=thisTrait.name))
+
+ #XZ: Symbol column
+ if thisTrait.db.type =="ProbeSet":
+ if thisTrait.symbol:
+ tr.append(TDCell(HT.TD(thisTrait.symbol, Class="fs12 fwn ffl b1 c222"), text=thisTrait.symbol, val=thisTrait.symbol.upper()))
+ else:
+ tr.append(TDCell(HT.TD('NA', Class="fs12 fwn ffl b1 c222"), text='NA', val='NA'))
+ elif thisTrait.db.type =="Publish":
+ AbbreviationString = "--"
+ if (thisTrait.post_publication_abbreviation != None):
+ AbbreviationString = thisTrait.post_publication_abbreviation
+
+ 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 = "--"
+
+ if AbbreviationString == "--":
+ tr.append(TDCell(HT.TD('NA', Class="fs12 fwn ffl b1 c222"), text='NA', val='NA'))
+ else:
+ tr.append(TDCell(HT.TD(AbbreviationString, Class="fs12 fwn ffl b1 c222"), text=AbbreviationString, val=AbbreviationString.upper()))
+ else:
+ tr.append(TDCell(HT.TD(thisTrait.name, Class="fs12 fwn ffl b1 c222"), text=thisTrait.name, val=thisTrait.name))
+
+ #XZ: Description column
+ if thisTrait.db.type =="ProbeSet" or thisTrait.db.type == "Temp":
+ tr.append(TDCell(HT.TD(thisTrait.description, Class="fs12 fwn ffl b1 c222"), text=thisTrait.description, val=thisTrait.description.upper()))
+ elif thisTrait.db.type =="Publish":
+ 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
+ tr.append(TDCell(HT.TD(PhenotypeString, Class="fs12 fwn ffl b1 c222"), text=PhenotypeString, val=PhenotypeString.upper()))
+ else:
+ tr.append(TDCell(HT.TD(thisTrait.name, Class="fs12 fwn ffl b1 c222"), text=thisTrait.name, val=thisTrait.name))
+
+ tr.append(TDCell(HT.TD(allcorrelations[i][1], Class="fs12 fwn ffl b1 c222", align='right'), text=allcorrelations[i][1], val=allcorrelations[i][1]))
+
+ #partial correlation result
+ try:
+ repr = '%3.3f' % float(allcorrelations[i][2])
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'), text=repr, val=abs(allcorrelations[i][2])))
+ except:
+ repr = 'NA'
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='left'), text=repr, val=0 ))
+
+ repr = webqtlUtil.SciFloat(allcorrelations[i][3])
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", nowrap='ON', align='right'), text=repr, val=allcorrelations[i][3]))
+
+ #zero order correlation result
+ repr = '%3.3f' % float(allcorrelations[i][4])
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'), text=repr, val=abs(allcorrelations[i][4])))
+
+ repr = webqtlUtil.SciFloat(allcorrelations[i][5])
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", nowrap='ON', align='right'), text=repr, val=allcorrelations[i][5]))
+
+ #delta
+ try:
+ repr = '%3.3f' % ( float(allcorrelations[i][2]) - float(allcorrelations[i][4]) )
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='right'), text=repr, val=repr ))
+ except:
+ repr = 'NA'
+ tr.append(TDCell(HT.TD(repr, Class="fs12 fwn ffl b1 c222", align='left'), text=repr, val=0 ))
+
+ tblobj['body'].append(tr)
+
+ 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=sortby, tableID = "sortable", addIndex = "1"), Id="sortable")
+ form.append(div)
+
+
+ TD_LR.append(HT.Center(form),HT.P())
+
+ self.dict['body'] = str(TD_LR)
+ # updated by NL, moved js function xmlhttpPost() and updatepage() to dhtml.js
+ self.dict['js1'] = ''
+ self.dict['title'] = 'Partial Correlation Result'
+
diff --git a/web/webqtl/correlation/PlotCorrelationPage.py b/web/webqtl/correlation/PlotCorrelationPage.py
new file mode 100755
index 00000000..23d2ccde
--- /dev/null
+++ b/web/webqtl/correlation/PlotCorrelationPage.py
@@ -0,0 +1,683 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by Ning Liu 2011/01/11
+
+import string
+import piddle as pid
+import os
+
+from htmlgen import HTMLgen2 as HT
+
+from utility import svg #Code using this module currently commented out
+from utility import Plot
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+from correlation import correlationFunction
+
+#########################################
+# PlotCorrelationPage
+#########################################
+class PlotCorrelationPage(templatePage):
+ corrMinInformative = 4
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ self.initializeDisplayParameters(fd)
+
+ if not fd.genotype:
+ fd.readGenotype()
+
+ if fd.allstrainlist:
+ mdpchoice = fd.formdata.getvalue('MDPChoice')
+ if mdpchoice == "1":
+ strainlist = fd.f1list + fd.strainlist
+ elif mdpchoice == "2":
+ strainlist = []
+ strainlist2 = fd.f1list + fd.strainlist
+ for strain in fd.allstrainlist:
+ if strain not in strainlist2:
+ strainlist.append(strain)
+ #So called MDP Panel
+ if strainlist:
+ strainlist = fd.f1list+fd.parlist+strainlist
+ else:
+ strainlist = fd.allstrainlist
+ fd.readData(fd.allstrainlist)
+ else:
+ mdpchoice = None
+ strainlist = fd.strainlist
+ fd.readData()
+
+ #if fd.allstrainlist:
+ # fd.readData(fd.allstrainlist)
+ # strainlist = fd.allstrainlist
+ #else:
+ # fd.readData()
+ # strainlist = fd.strainlist
+
+
+ if not self.openMysql():
+ return
+
+ isSampleCorr = 0 #XZ: initial value is false
+ isTissueCorr = 0 #XZ: initial value is false
+
+ #Javascript functions (showCorrelationPlot2, showTissueCorrPlot) have made sure the correlation type is either sample correlation or tissue correlation.
+ if (self.database and (self.ProbeSetID != 'none')):
+ isSampleCorr = 1
+ elif (self.X_geneSymbol and self.Y_geneSymbol):
+ isTissueCorr = 1
+ else:
+ heading = "Correlation Type Error"
+ detail = ["For the input parameters, GN can not recognize the correlation type is sample correlation or tissue correlation."]
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ TD_LR = HT.TD(colspan=2,height=200,width="100%",bgColor='#eeeeee', align="left", wrap="off")
+
+
+ dataX=[]
+ dataY=[]
+ dataZ=[] # shortname
+ fullTissueName=[]
+ xlabel = ''
+ ylabel = ''
+
+ if isTissueCorr:
+ dataX, dataY, xlabel, ylabel, dataZ, fullTissueName = self.getTissueLabelsValues(X_geneSymbol=self.X_geneSymbol, Y_geneSymbol=self.Y_geneSymbol, TissueProbeSetFreezeId=self.TissueProbeSetFreezeId)
+ plotHeading = HT.Paragraph('Tissue Correlation Scatterplot')
+ plotHeading.__setattr__("class","title")
+
+ if isSampleCorr:
+ plotHeading = HT.Paragraph('Sample Correlation Scatterplot')
+ plotHeading.__setattr__("class","title")
+
+ #XZ: retrieve trait 1 info, Y axis
+ trait1_data = [] #trait 1 data
+ trait1Url = ''
+
+ try:
+ Trait1 = webqtlTrait(db=self.database, name=self.ProbeSetID, cellid=self.CellID, cursor=self.cursor)
+ Trait1.retrieveInfo()
+ Trait1.retrieveData()
+ except:
+ heading = "Retrieve Data"
+ detail = ["The database you just requested has not been established yet."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ trait1_data = Trait1.exportData(strainlist)
+ if Trait1.db.type == 'Publish' and Trait1.confidential:
+ trait1Url = Trait1.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=Trait1.authorized_users)
+ else:
+ trait1Url = Trait1.genHTML(dispFromDatabase=1)
+ ylabel = '%s : %s' % (Trait1.db.shortname, Trait1.name)
+ if Trait1.cellid:
+ ylabel += ' : ' + Trait1.cellid
+
+
+ #XZ, retrieve trait 2 info, X axis
+ traitdata2 = [] #trait 2 data
+ _vals = [] #trait 2 data
+ trait2Url = ''
+
+ if ( self.database2 and (self.ProbeSetID2 != 'none') ):
+ try:
+ Trait2 = webqtlTrait(db=self.database2, name=self.ProbeSetID2, cellid=self.CellID2, cursor=self.cursor)
+ Trait2.retrieveInfo()
+ Trait2.retrieveData()
+ except:
+ heading = "Retrieve Data"
+ detail = ["The database you just requested has not been established yet."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ if Trait2.db.type == 'Publish' and Trait2.confidential:
+ trait2Url = Trait2.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=Trait2.authorized_users)
+ else:
+ trait2Url = Trait2.genHTML(dispFromDatabase=1)
+ traitdata2 = Trait2.exportData(strainlist)
+ _vals = traitdata2[:]
+ xlabel = '%s : %s' % (Trait2.db.shortname, Trait2.name)
+ if Trait2.cellid:
+ xlabel += ' : ' + Trait2.cellid
+ else:
+ for item in strainlist:
+ if fd.allTraitData.has_key(item):
+ _vals.append(fd.allTraitData[item].val)
+ else:
+ _vals.append(None)
+
+ if fd.identification:
+ xlabel = fd.identification
+ else:
+ xlabel = "User Input Data"
+
+ try:
+ Trait2 = webqtlTrait(fullname=fd.formdata.getvalue('fullname'), cursor=self.cursor)
+ trait2Url = Trait2.genHTML(dispFromDatabase=1)
+ except:
+ trait2Url = xlabel
+
+ if (_vals and trait1_data):
+ if len(_vals) != len(trait1_data):
+ errors = HT.Blockquote(HT.Font('Error: ',color='red'),HT.Font('The number of traits are inconsistent, Program quit',color='black'))
+ errors.__setattr__("class","subtitle")
+ TD_LR.append(errors)
+ self.dict['body'] = str(TD_LR)
+ return
+
+ for i in range(len(_vals)):
+ if _vals[i]!= None and trait1_data[i]!= None:
+ dataX.append(_vals[i])
+ dataY.append(trait1_data[i])
+ strainName = strainlist[i]
+ if self.showstrains:
+ dataZ.append(webqtlUtil.genShortStrainName(RISet=fd.RISet, input_strainName=strainName))
+ else:
+ heading = "Correlation Plot"
+ detail = ['Empty Dataset for sample correlation, please check your data.']
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ #XZ: We have gotten all data for both traits.
+ if len(dataX) >= self.corrMinInformative:
+
+ if self.rankOrder == 0:
+ rankPrimary = 0
+ rankSecondary = 1
+ else:
+ rankPrimary = 1
+ rankSecondary = 0
+
+ lineColor = self.setLineColor();
+ symbolColor = self.setSymbolColor();
+ idColor = self.setIdColor();
+
+ c = pid.PILCanvas(size=(self.plotSize, self.plotSize*0.90))
+ data_coordinate = Plot.plotXY(canvas=c, dataX=dataX, dataY=dataY, rank=rankPrimary, dataLabel = dataZ, labelColor=pid.black, lineSize=self.lineSize, lineColor=lineColor, idColor=idColor, idFont=self.idFont, idSize=self.idSize, symbolColor=symbolColor, symbolType=self.symbol, filled=self.filled, symbolSize=self.symbolSize, XLabel=xlabel, connectdot=0, YLabel=ylabel, title='', fitcurve=self.showline, displayR =1, offset= (90, self.plotSize/20, self.plotSize/10, 90), showLabel = self.showIdentifiers)
+
+ if rankPrimary == 1:
+ dataXlabel, dataYlabel = webqtlUtil.calRank(xVals=dataX, yVals=dataY, N=len(dataX))
+ else:
+ dataXlabel, dataYlabel = dataX, dataY
+
+ gifmap1 = HT.Map(name='CorrelationPlotImageMap1')
+
+ for i, item in enumerate(data_coordinate):
+ one_rect_coordinate = "%d, %d, %d, %d" % (item[0] - 5, item[1] - 5, item[0] + 5, item[1] + 5)
+ if isTissueCorr:
+ one_rect_title = "%s (%s, %s)" % (fullTissueName[i], dataXlabel[i], dataYlabel[i])
+ else:
+ one_rect_title = "%s (%s, %s)" % (dataZ[i], dataXlabel[i], dataYlabel[i])
+ gifmap1.areas.append(HT.Area(shape='rect',coords=one_rect_coordinate, title=one_rect_title) )
+
+ filename= webqtlUtil.genRandStr("XY_")
+ c.save(webqtlConfig.IMGDIR+filename, format='gif')
+ img1=HT.Image('/image/'+filename+'.gif',border=0, usemap='#CorrelationPlotImageMap1')
+
+ mainForm_1 = 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, 'ProbeSetID2':'_', 'database2':'_', 'CellID2':'_', 'allstrainlist':string.join(fd.strainlist, " "), 'traitList': fd.formdata.getvalue("traitList")}
+ if fd.incparentsf1:
+ hddn['incparentsf1'] = 'ON'
+ for key in hddn.keys():
+ mainForm_1.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ if isSampleCorr:
+ mainForm_1.append(HT.P(), HT.Blockquote(HT.Strong('X axis:'),HT.Blockquote(trait2Url),HT.Strong('Y axis:'),HT.Blockquote(trait1Url), style='width: %spx;' % self.plotSize, wrap="hard"))
+
+ graphForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='MDP_Form',submit=HT.Input(type='hidden'))
+ graph_hddn = self.setHiddenParameters(fd, rankPrimary)
+ webqtlUtil.exportData(graph_hddn, fd.allTraitData) #XZ: This is necessary to replot with different groups of strains
+
+ for key in graph_hddn.keys():
+ graphForm.append(HT.Input(name=key, value=graph_hddn[key], type='hidden'))
+
+ options = self.createOptionsMenu(fd, mdpchoice)
+
+ if (self.showOptions == '0'):
+ showOptionsButton = HT.Input(type='button' ,name='optionsButton',value='Hide Options', onClick="showHideOptions();", Class="button")
+ else:
+ showOptionsButton = HT.Input(type='button' ,name='optionsButton',value='Show Options', onClick="showHideOptions();", Class="button")
+
+ # updated by NL: 12-07-2011 add variables for tissue abbreviation page
+ if isTissueCorr:
+ graphForm.append(HT.Input(name='shortTissueName', value='', type='hidden'))
+ graphForm.append(HT.Input(name='fullTissueName', value='', type='hidden'))
+ shortTissueNameStr=string.join(dataZ, ",")
+ fullTissueNameStr=string.join(fullTissueName, ",")
+
+ tissueAbbrButton=HT.Input(type='button' ,name='tissueAbbrButton',value='Show Abbreviations', onClick="showTissueAbbr('MDP_Form','%s','%s')" % (shortTissueNameStr,fullTissueNameStr), Class="button")
+ graphForm.append(showOptionsButton,' ',tissueAbbrButton, HT.BR(), HT.BR())
+ else:
+ graphForm.append(showOptionsButton, HT.BR(), HT.BR())
+
+ graphForm.append(options, HT.BR())
+ graphForm.append(HT.HR(), HT.BR(), HT.P())
+
+ TD_LR.append(plotHeading, HT.BR(),graphForm, HT.BR(), gifmap1, HT.P(), img1, HT.P(), mainForm_1)
+ TD_LR.append(HT.BR(), HT.HR(color="grey", size=5, width="100%"))
+
+
+
+ c = pid.PILCanvas(size=(self.plotSize, self.plotSize*0.90))
+ data_coordinate = Plot.plotXY(canvas=c, dataX=dataX, dataY=dataY, rank=rankSecondary, dataLabel = dataZ, labelColor=pid.black,lineColor=lineColor, lineSize=self.lineSize, idColor=idColor, idFont=self.idFont, idSize=self.idSize, symbolColor=symbolColor, symbolType=self.symbol, filled=self.filled, symbolSize=self.symbolSize, XLabel=xlabel, connectdot=0, YLabel=ylabel,title='', fitcurve=self.showline, displayR =1, offset= (90, self.plotSize/20, self.plotSize/10, 90), showLabel = self.showIdentifiers)
+
+ if rankSecondary == 1:
+ dataXlabel, dataYlabel = webqtlUtil.calRank(xVals=dataX, yVals=dataY, N=len(dataX))
+ else:
+ dataXlabel, dataYlabel = dataX, dataY
+
+ gifmap2 = HT.Map(name='CorrelationPlotImageMap2')
+
+ for i, item in enumerate(data_coordinate):
+ one_rect_coordinate = "%d, %d, %d, %d" % (item[0] - 6, item[1] - 6, item[0] + 6, item[1] + 6)
+ if isTissueCorr:
+ one_rect_title = "%s (%s, %s)" % (fullTissueName[i], dataXlabel[i], dataYlabel[i])
+ else:
+ one_rect_title = "%s (%s, %s)" % (dataZ[i], dataXlabel[i], dataYlabel[i])
+
+ gifmap2.areas.append(HT.Area(shape='rect',coords=one_rect_coordinate, title=one_rect_title) )
+
+ filename= webqtlUtil.genRandStr("XY_")
+ c.save(webqtlConfig.IMGDIR+filename, format='gif')
+ img2=HT.Image('/image/'+filename+'.gif',border=0, usemap='#CorrelationPlotImageMap2')
+
+ mainForm_2 = HT.Form( cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='showDatabase2', submit=HT.Input(type='hidden'))
+ hddn = {'FormID':'showDatabase2','ProbeSetID':'_','database':'_','CellID':'_','RISet':fd.RISet, 'ProbeSetID2':'_', 'database2':'_', 'CellID2':'_', 'allstrainlist':string.join(fd.strainlist, " "), 'traitList': fd.formdata.getvalue("traitList")}
+ if fd.incparentsf1:
+ hddn['incparentsf1'] = 'ON'
+ for key in hddn.keys():
+ mainForm_2.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ if isSampleCorr:
+ mainForm_2.append(HT.P(), HT.Blockquote(HT.Strong('X axis:'),HT.Blockquote(trait2Url),HT.Strong('Y axis:'),HT.Blockquote(trait1Url), style='width:%spx;' % self.plotSize))
+
+
+ TD_LR.append(HT.BR(), HT.P())
+ TD_LR.append('\n', gifmap2, HT.P(), HT.P(), img2, HT.P(), mainForm_2)
+
+ self.dict['body'] = str(TD_LR)
+ else:
+ heading = "Correlation Plot"
+ detail = ['Fewer than %d strain data were entered for %s data set. No statitical analysis has been attempted.' % (self.corrMinInformative, fd.RISet)]
+ self.error(heading=heading,detail=detail)
+ return
+
+
+
+ def initializeDisplayParameters(self, fd):
+ """
+ Initializes all of the PlotCorrelationPage class parameters,
+ acquiring most values from the formdata (fd)
+ """
+
+ rankOrderString = fd.formdata.getvalue('rankOrder')
+ if rankOrderString == "1":
+ self.rankOrder = 1
+ else:
+ self.rankOrder = 0
+
+ self.dict['title'] = 'Correlation X-Y Scatterplot'
+ focusScript = "onLoad=\"document.getElementsByName('plotSize')[0].focus();\";"
+ self.dict['js2'] = focusScript
+
+ self.showstrains = fd.formdata.getvalue('ShowStrains')
+ self.showline = fd.formdata.getvalue('ShowLine')
+ self.X_geneSymbol = fd.formdata.getvalue('X_geneSymbol','')
+ self.Y_geneSymbol = fd.formdata.getvalue('Y_geneSymbol','')
+ self.TissueProbeSetFreezeId = fd.formdata.getvalue('TissueProbeSetFreezeId', '1')
+
+ self.symbolColor = fd.formdata.getvalue('symbolColor', 'black')
+ self.symbol = fd.formdata.getvalue('symbol', 'circle')
+ self.filled = fd.formdata.getvalue('filled', 'yes')
+ self.symbolSize = fd.formdata.getvalue('symbolSize', 'tiny')
+ self.idColor = fd.formdata.getvalue('idColor', 'blue')
+ self.idFont = fd.formdata.getvalue('idFont', 'arial')
+ self.idSize = fd.formdata.getvalue('idSize', '14')
+ self.lineColor = fd.formdata.getvalue('lineColor', 'grey')
+ self.lineSize = fd.formdata.getvalue('lineSize', 'medium')
+ self.showOptions = fd.formdata.getvalue('showOptions', '0')
+
+ try:
+ self.plotSize = int(fd.formdata.getvalue('plotSize', 900))
+ except:
+ self.plotSize = 900
+ try:
+ self.showIdentifiers = int(fd.formdata.getvalue('showIdentifiers', 1))
+ except:
+ self.showIdentifiers = 1
+
+ self.database = fd.formdata.getvalue('database')
+ self.ProbeSetID = fd.formdata.getvalue('ProbeSetID', 'none')
+ self.CellID = fd.formdata.getvalue('CellID')
+
+ self.database2 = fd.formdata.getvalue('database2')
+ self.ProbeSetID2 = fd.formdata.getvalue('ProbeSetID2', 'none')
+ self.CellID2 = fd.formdata.getvalue('CellID2')
+
+ def createOptionsMenu(self, fd, mdpchoice):
+ """
+ Create all the HTML for the options menu; the first if/else statements
+ determine whether the Div container holding all the other html is visible
+ or not.
+ """
+
+ if (self.showOptions == '0'):
+ options = HT.Div(name="options", id="options", style="display: none")
+ self.showOptions = '1'
+ else:
+ options = HT.Div(name="options", id="options", style="display: ''")
+ self.showOptions = '0'
+
+ if self.showIdentifiers:
+ containerTable = HT.TableLite(cellspacing=1, width=730, height=150, border=1)
+ else:
+ containerTable = HT.TableLite(cellspacing=1, width=730, height=130, border=1)
+
+ if self.showIdentifiers:
+ containerTable = HT.TableLite(cellspacing=1, width=730, height=150, border=1)
+ else:
+ containerTable = HT.TableLite(cellspacing=1, width=730, height=130, border=1)
+
+ containerRow = HT.TR()
+ containerCell = HT.TD(valign="middle", align="center")
+
+ optionsTable = HT.TableLite(Class="collap", cellspacing=2, width=700)
+
+ sizeOptions = HT.TR(align="right")
+ tagOptions = HT.TR(align="right")
+ markerOptions = HT.TR(align="right")
+ lineOptions = HT.TR(align="right")
+ replot_mdpOptions = HT.TR(align="right")
+
+ sizeOptions.append(HT.TD(HT.Bold("Size: "), " "*1, HT.Input(type='text' ,name='plotSize', value=self.plotSize, style="background-color: #FFFFFF; width: 50px;", onChange="checkWidth();"), align="left"))
+
+ idColorSel = HT.Select(name="idColorSel", onChange="changeIdColor(); submit();", selected=self.idColor)
+ idColorSel.append(("blue", "blue"))
+ idColorSel.append(("green", "green"))
+ idColorSel.append(("red", "red"))
+ idColorSel.append(("yellow", "yellow"))
+ idColorSel.append(("white", "white"))
+ idColorSel.append(("purple", "purple"))
+ idColorSel.append(("brown", "brown"))
+ idColorSel.append(("grey", "grey"))
+ idColorSel.append(("black","black"))
+
+ idFontSel = HT.Select(name="idFontSel", onChange="changeIdFont(); submit();", selected=self.idFont)
+ idFontSel.append(("Arial", "arial"))
+ idFontSel.append(("Trebuchet", "trebuc"))
+ idFontSel.append(("Verdana", "verdana"))
+ idFontSel.append(("Georgia", "Georgia"))
+ idFontSel.append(("Courier", "cour"))
+
+ idSizeSel = HT.Select(name="idSizeSel", onChange="changeIdSize(); submit();", selected=self.idSize)
+ idSizeSel.append(("10", "10"))
+ idSizeSel.append(("12", "12"))
+ idSizeSel.append(("14", "14"))
+ idSizeSel.append(("16", "16"))
+ idSizeSel.append(("18", "18"))
+
+ if self.showIdentifiers:
+ tagButton = HT.TD(HT.Input(type='button' ,name='',value=' Hide Tags ',onClick="this.form.showIdentifiers.value=0;submit();", Class="button"), align="right")
+ else:
+ tagButton = HT.TD(HT.Input(type='button' ,name='',value=' Show Tags ',onClick="this.form.showIdentifiers.value=1;submit();", Class="button"), align="right")
+
+ tagOptions.append(HT.TD(HT.Text(HT.Bold("Tag Settings: ")), align="left"))
+ tagOptions.append(HT.TD(HT.Text(text="Font: "), idFontSel))
+ tagOptions.append(HT.TD(HT.Text(text="Color: "), idColorSel))
+ tagOptions.append(HT.TD(HT.Text(text="Point: "), idSizeSel))
+ tagOptions.append(tagButton)
+ optionsTable.append(sizeOptions, tagOptions)
+
+ if fd.allstrainlist and mdpchoice:
+ allStrainList = HT.Input(name='allstrainlist', value=string.join(fd.allstrainlist, " "), type='hidden')
+ mdpChoice = HT.Input(name='MDPChoice', value=mdpchoice, type='hidden')
+ btn0 = HT.Input(type='button' ,name='',value='All Cases',onClick="this.form.MDPChoice.value=0;submit();", Class="button")
+ btn1 = HT.Input(type='button' ,name='',value='%s Only' % fd.RISet,onClick="this.form.MDPChoice.value=1;submit();", Class="button")
+ btn2 = HT.Input(type='button' ,name='',value='MDP Only', onClick="this.form.MDPChoice.value=2;submit();", Class="button")
+
+
+ colorSel = HT.Select(name="colorSel", onChange="changeSymbolColor(); submit();", selected=self.symbolColor)
+ colorSel.append(("red", "red"))
+ colorSel.append(("green", "green"))
+ colorSel.append(("blue", "blue"))
+ colorSel.append(("yellow", "yellow"))
+ colorSel.append(("purple", "purple"))
+ colorSel.append(("brown", "brown"))
+ colorSel.append(("grey", "grey"))
+ colorSel.append(("black","black"))
+
+ symbolSel = HT.Select(name="symbolSel", onChange="changeSymbol(); submit();", selected=self.symbol)
+ symbolSel.append(("4-star","4-star"))
+ symbolSel.append(("3-star","3-star"))
+ symbolSel.append(("cross", "cross"))
+ symbolSel.append(("circle","circle"))
+ symbolSel.append(("diamond", "diamond"))
+ symbolSel.append(("square", "square"))
+ symbolSel.append(("vert rect", "vertRect"))
+ symbolSel.append(("hori rect", "horiRect"))
+
+ sizeSel = HT.Select(name="sizeSel", onChange="changeSize(); submit();", selected=self.symbolSize)
+ sizeSel.append(("tiny","tiny"))
+ sizeSel.append(("small","small"))
+ sizeSel.append(("medium","medium"))
+ sizeSel.append(("large","large"))
+
+ fillSel = HT.Select(name="fillSel", onChange="changeFilled(); submit();", selected=self.filled)
+ fillSel.append(("no","no"))
+ fillSel.append(("yes","yes"))
+
+ lineColorSel = HT.Select(name="lineColorSel", onChange="changeLineColor(); submit();", selected=self.lineColor)
+ lineColorSel.append(("red", "red"))
+ lineColorSel.append(("green", "green"))
+ lineColorSel.append(("blue", "blue"))
+ lineColorSel.append(("yellow", "yellow"))
+ lineColorSel.append(("purple", "purple"))
+ lineColorSel.append(("brown", "brown"))
+ lineColorSel.append(("grey", "grey"))
+ lineColorSel.append(("black","black"))
+
+ lineSizeSel = HT.Select(name="lineSizeSel", onChange="changeLineSize(); submit();", selected=self.lineSize)
+ lineSizeSel.append(("thin", "thin"))
+ lineSizeSel.append(("medium", "medium"))
+ lineSizeSel.append(("thick", "thick"))
+
+
+ markerOptions.append(HT.TD(HT.Text(HT.Bold("Marker Settings: ")), align="left"))
+ markerOptions.append(HT.TD(HT.Text(text="Marker: "), symbolSel))
+ markerOptions.append(HT.TD(HT.Text(text="Color: "), colorSel))
+ markerOptions.append(HT.TD(HT.Text(text="Fill: "), fillSel))
+ markerOptions.append(HT.TD(HT.Text(text="Size: "), sizeSel))
+
+ lineOptions.append(HT.TD(HT.Text(HT.Bold("Line Settings: ")), align="left"))
+ lineOptions.append(HT.TD(HT.Text(text="Width: "), lineSizeSel))
+ lineOptions.append(HT.TD(HT.Text(text="Color: "), lineColorSel))
+
+ replotButton = HT.Input(type='button', name='', value=' Replot ',onClick="checkWidth(); submit();", Class="button")
+
+ if fd.allstrainlist and mdpchoice:
+ replot_mdpOptions.append(HT.TD(replotButton, align="left"), HT.TD(allStrainList, mdpChoice, btn0, btn1, btn2, align="center", colspan=3))
+ optionsTable.append(markerOptions, lineOptions, HT.TR(HT.TD(HT.BR())), replot_mdpOptions )
+ else:
+ replot_mdpOptions.append(HT.TD(replotButton, align="left"))
+ optionsTable.append(markerOptions, lineOptions, HT.TR(HT.TD(HT.BR())), replot_mdpOptions)
+
+ containerCell.append(optionsTable)
+ containerRow.append(containerCell)
+ containerTable.append(containerRow)
+
+ options.append(containerTable)
+
+ return options
+
+ def setHiddenParameters(self, fd, rankPrimary):
+ """
+ Create the dictionary of hidden form parameters from PlotCorrelationPage's class parameters
+ """
+
+ graph_hddn = {'FormID':'showCorrelationPlot','RISet':fd.RISet, 'identification':fd.identification, "incparentsf1":1, "showIdentifiers":self.showIdentifiers}
+
+ if self.database: graph_hddn['database']=self.database
+ if self.ProbeSetID: graph_hddn['ProbeSetID']=self.ProbeSetID
+ if self.CellID: graph_hddn['CellID']=self.CellID
+ if self.database2: graph_hddn['database2']=self.database2
+ if self.ProbeSetID2: graph_hddn['ProbeSetID2']=self.ProbeSetID2
+ if self.CellID2: graph_hddn['CellID2']=self.CellID2
+ if self.showstrains: graph_hddn['ShowStrains']=self.showstrains
+ if self.showline: graph_hddn['ShowLine']=self.showline
+ if self.X_geneSymbol: graph_hddn['X_geneSymbol']=self.X_geneSymbol
+ if self.Y_geneSymbol: graph_hddn['Y_geneSymbol']=self.Y_geneSymbol
+ if self.TissueProbeSetFreezeId: graph_hddn['TissueProbeSetFreezeId']=self.TissueProbeSetFreezeId
+ if self.rankOrder: graph_hddn['rankOrder'] = rankPrimary
+ if fd.formdata.getvalue('fullname'): graph_hddn['fullname']=fd.formdata.getvalue('fullname')
+ if self.lineColor: graph_hddn['lineColor'] = self.lineColor
+ if self.lineSize: graph_hddn['lineSize'] = self.lineSize
+ if self.idColor: graph_hddn['idColor'] = self.idColor
+ if self.idFont: graph_hddn['idFont'] = self.idFont
+ if self.idSize: graph_hddn['idSize'] = self.idSize
+ if self.symbolColor: graph_hddn['symbolColor'] = self.symbolColor
+ if self.symbol: graph_hddn['symbol'] = self.symbol
+ if self.filled: graph_hddn['filled'] = self.filled
+ if self.symbolSize: graph_hddn['symbolSize'] = self.symbolSize
+ if self.showOptions: graph_hddn['showOptions'] = self.showOptions
+
+ return graph_hddn
+
+ def setIdColor(self):
+ """
+ Set the plot tag/ID color based upon the value of the idColor class parameter
+ """
+
+ if self.idColor == 'black':
+ idColor = pid.black
+ elif self.idColor == 'white':
+ idColor = pid.white
+ elif self.idColor == 'yellow':
+ idColor = pid.yellow
+ elif self.idColor == 'grey':
+ idColor = pid.grey
+ elif self.idColor == 'blue':
+ idColor = pid.blue
+ elif self.idColor == 'purple':
+ idColor = pid.purple
+ elif self.idColor == 'brown':
+ idColor = pid.brown
+ elif self.idColor == 'green':
+ idColor = pid.green
+ else:
+ idColor = pid.red
+
+ return idColor
+
+ def setSymbolColor(self):
+ """
+ Set the plot symbol color based upon the value of the symbolColor class parameter
+ """
+
+ if self.symbolColor == 'black':
+ symbolColor = pid.black
+ elif self.symbolColor == 'grey':
+ symbolColor = pid.grey
+ elif self.symbolColor == 'yellow':
+ symbolColor = pid.yellow
+ elif self.symbolColor == 'blue':
+ symbolColor = pid.blue
+ elif self.symbolColor == 'purple':
+ symbolColor = pid.purple
+ elif self.symbolColor == 'brown':
+ symbolColor = pid.brown
+ elif self.symbolColor== 'green':
+ symbolColor = pid.green
+ else:
+ symbolColor = pid.red
+
+ return symbolColor
+
+ def setLineColor(self):
+ """
+ Set the plot line color based upon the lineColor class parameter
+ """
+
+ if self.lineColor == 'black':
+ lineColor = pid.black
+ elif self.lineColor == 'grey':
+ lineColor = pid.grey
+ elif self.lineColor == 'yellow':
+ lineColor = pid.yellow
+ elif self.lineColor == 'blue':
+ lineColor = pid.blue
+ elif self.lineColor == 'purple':
+ lineColor = pid.purple
+ elif self.lineColor == 'brown':
+ lineColor = pid.brown
+ elif self.lineColor== 'green':
+ lineColor = pid.green
+ else:
+ lineColor = pid.red
+
+ return lineColor
+
+
+ def getTissueLabelsValues(self, X_geneSymbol=None, Y_geneSymbol=None, TissueProbeSetFreezeId=None ):
+
+ dataX = []
+ dataY = []
+ data_fullLabel = []
+ data_shortLabel = []
+ # updated by NL, 2011-01-11 using new function getTissueProbeSetXRefInfo to get dataId value
+ X_symbolList,X_geneIdDict,X_dataIdDict,X_ChrDict,X_MbDict,X_descDict,X_pTargetDescDict = correlationFunction.getTissueProbeSetXRefInfo(cursor=self.cursor,GeneNameLst=[X_geneSymbol],TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+ Y_symbolList,Y_geneIdDict,Y_dataIdDict,Y_ChrDict,Y_MbDict,Y_descDict,Y_pTargetDescDict = correlationFunction.getTissueProbeSetXRefInfo(cursor=self.cursor,GeneNameLst=[Y_geneSymbol],TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+ # in dataIdDict, key is the lower cased geneSymbol
+ X_DataId = X_dataIdDict[X_geneSymbol.lower()]
+ Y_DataId = Y_dataIdDict[Y_geneSymbol.lower()]
+
+ self.cursor.execute("SELECT TissueID,value FROM TissueProbeSetData WHERE Id = %d ORDER BY TissueID" % int(X_DataId) )
+ results = self.cursor.fetchall()
+ for item in results:
+ TissueID, Value = item
+ dataX.append(Value)
+ self.cursor.execute("SELECT Tissue.Name, Tissue.Short_Name FROM Tissue WHERE Id = %d" % int(TissueID) )
+ temp = self.cursor.fetchone()
+ data_fullLabel.append( temp[0] )
+ data_shortLabel.append( temp[1] )
+
+ self.cursor.execute("SELECT TissueID,value FROM TissueProbeSetData WHERE Id = %d ORDER BY TissueID" % int(Y_DataId) )
+ results = self.cursor.fetchall()
+ for item in results:
+ TissueID, Value = item
+ dataY.append(Value)
+
+ X_label = "%s" % X_geneSymbol
+ Y_label = "%s" % Y_geneSymbol
+
+ return dataX, dataY, X_label, Y_label, data_shortLabel, data_fullLabel
diff --git a/web/webqtl/correlation/__init__.py b/web/webqtl/correlation/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/correlation/correlationFunction.py b/web/webqtl/correlation/correlationFunction.py
new file mode 100755
index 00000000..cc19f54e
--- /dev/null
+++ b/web/webqtl/correlation/correlationFunction.py
@@ -0,0 +1,923 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by NL 2011/03/23
+
+
+import math
+import rpy2.robjects
+import pp
+import string
+
+from utility import webqtlUtil
+from base.webqtlTrait import webqtlTrait
+from dbFunction import webqtlDatabaseFunction
+
+
+
+#XZ: The input 'controls' is String. It contains the full name of control traits.
+#XZ: The input variable 'strainlst' is List. It contains the strain names of primary trait.
+#XZ: The returned tcstrains is the list of list [[],[]...]. So are tcvals and tcvars. The last returned parameter is list of numbers.
+#XZ, 03/29/2010: For each returned control trait, there is no None value in it.
+def controlStrains(controls, strainlst):
+
+ controls = controls.split(',')
+
+ cvals = {}
+ for oneTraitName in controls:
+ oneTrait = webqtlTrait(fullname=oneTraitName, cursor=webqtlDatabaseFunction.getCursor() )
+ oneTrait.retrieveData()
+ cvals[oneTraitName] = oneTrait.data
+
+ tcstrains = []
+ tcvals = []
+ tcvars = []
+
+ for oneTraitName in controls:
+ strains = []
+ vals = []
+ vars = []
+
+ for _strain in strainlst:
+ if cvals[oneTraitName].has_key(_strain):
+ _val = cvals[oneTraitName][_strain].val
+ if _val != None:
+ strains.append(_strain)
+ vals.append(_val)
+ vars.append(None)
+
+ tcstrains.append(strains)
+ tcvals.append(vals)
+ tcvars.append(vars)
+
+ return tcstrains, tcvals, tcvars, [len(x) for x in tcstrains]
+
+
+
+#XZ, 03/29/2010: After execution of functon "controlStrains" and "fixStrains", primary trait and control traits have the same strains and in the same order. There is no 'None' value in them.
+def fixStrains(_strains,_controlstrains,_vals,_controlvals,_vars,_controlvars):
+ """Corrects strains, vals, and vars so that all contrain only those strains common
+ to the reference trait and all control traits."""
+
+ def dictify(strains,vals,vars):
+ subdict = {}
+ for i in xrange(len(strains)):
+ subdict[strains[i]] = (vals[i],vars[i])
+ return subdict
+
+ #XZ: The 'dicts' is a list of dictionary. The first element is the dictionary of reference trait. The rest elements are for control traits.
+ dicts = []
+ dicts.append(dictify(_strains,_vals,_vars))
+
+ nCstrains = len(_controlstrains)
+ for i in xrange(nCstrains):
+ dicts.append(dictify(_controlstrains[i],_controlvals[i],_controlvars[i]))
+
+ _newstrains = []
+ _vals = []
+ _vars = []
+ _controlvals = [[] for x in xrange(nCstrains)]
+ _controlvars = [[] for x in xrange(nCstrains)]
+
+ for strain in _strains:
+ inall = True
+ for d in dicts:
+ if strain not in d:
+ inall = False
+ break
+ if inall:
+ _newstrains.append(strain)
+ _vals.append(dicts[0][strain][0])
+ _vars.append(dicts[0][strain][1])
+ for i in xrange(nCstrains):
+ _controlvals[i].append(dicts[i+1][strain][0])
+ _controlvars[i].append(dicts[i+1][strain][1])
+
+ return _newstrains, _vals, _controlvals, _vars, _controlvars
+
+
+#XZ, 6/15/2010: If there is no identical control traits, the returned list is empty.
+#else, the returned list has two elements of control trait name.
+def findIdenticalControlTraits ( controlVals, controlNames ):
+ nameOfIdenticalTraits = []
+
+ controlTraitNumber = len(controlVals)
+
+ if controlTraitNumber > 1:
+
+ #XZ: reset the precision of values and convert to string type
+ for oneTraitVal in controlVals:
+ for oneStrainVal in oneTraitVal:
+ oneStrainVal = '%.3f' % oneStrainVal
+
+ for i, oneTraitVal in enumerate( controlVals ):
+ for j in range(i+1, controlTraitNumber):
+ if oneTraitVal == controlVals[j]:
+ nameOfIdenticalTraits.append(controlNames[i])
+ nameOfIdenticalTraits.append(controlNames[j])
+
+ return nameOfIdenticalTraits
+
+#XZ, 6/15/2010: If there is no identical control traits, the returned list is empty.
+#else, the returned list has two elements of control trait name.
+#primaryVal is of list type. It contains value of primary trait.
+#primaryName is of string type.
+#controlVals is of list type. Each element is list too. Each element contain value of one control trait.
+#controlNames is of list type.
+def findIdenticalTraits (primaryVal, primaryName, controlVals, controlNames ):
+ nameOfIdenticalTraits = []
+
+ #XZ: reset the precision of values and convert to string type
+ for oneStrainVal in primaryVal:
+ oneStrainVal = '%.3f' % oneStrainVal
+
+ for oneTraitVal in controlVals:
+ for oneStrainVal in oneTraitVal:
+ oneStrainVal = '%.3f' % oneStrainVal
+
+ controlTraitNumber = len(controlVals)
+
+ if controlTraitNumber > 1:
+ for i, oneTraitVal in enumerate( controlVals ):
+ for j in range(i+1, controlTraitNumber):
+ if oneTraitVal == controlVals[j]:
+ nameOfIdenticalTraits.append(controlNames[i])
+ nameOfIdenticalTraits.append(controlNames[j])
+ break
+
+ if len(nameOfIdenticalTraits) == 0:
+ for i, oneTraitVal in enumerate( controlVals ):
+ if primaryVal == oneTraitVal:
+ nameOfIdenticalTraits.append(primaryName)
+ nameOfIdenticalTraits.append(controlNames[i])
+ break
+
+ return nameOfIdenticalTraits
+
+
+
+#XZ, 03/29/2010: The strains in primaryVal, controlVals, targetVals must be of the same number and in same order.
+#XZ: No value in primaryVal and controlVals could be None.
+
+def determinePartialsByR (primaryVal, controlVals, targetVals, targetNames, method='p'):
+
+ def compute_partial ( primaryVal, controlVals, targetVals, targetNames, method ):
+
+ rpy2.robjects.r("""
+pcor.test <- function(x,y,z,use="mat",method="p",na.rm=T){
+ # The partial correlation coefficient between x and y given z
+ #
+ # pcor.test is free and comes with ABSOLUTELY NO WARRANTY.
+ #
+ # x and y should be vectors
+ #
+ # z can be either a vector or a matrix
+ #
+ # use: There are two methods to calculate the partial correlation coefficient.
+ # One is by using variance-covariance matrix ("mat") and the other is by using recursive formula ("rec").
+ # Default is "mat".
+ #
+ # method: There are three ways to calculate the correlation coefficient,
+ # which are Pearson's ("p"), Spearman's ("s"), and Kendall's ("k") methods.
+ # The last two methods which are Spearman's and Kendall's coefficient are based on the non-parametric analysis.
+ # Default is "p".
+ #
+ # na.rm: If na.rm is T, then all the missing samples are deleted from the whole dataset, which is (x,y,z).
+ # If not, the missing samples will be removed just when the correlation coefficient is calculated.
+ # However, the number of samples for the p-value is the number of samples after removing
+ # all the missing samples from the whole dataset.
+ # Default is "T".
+
+ x <- c(x)
+ y <- c(y)
+ z <- as.data.frame(z)
+
+ if(use == "mat"){
+ p.use <- "Var-Cov matrix"
+ pcor = pcor.mat(x,y,z,method=method,na.rm=na.rm)
+ }else if(use == "rec"){
+ p.use <- "Recursive formula"
+ pcor = pcor.rec(x,y,z,method=method,na.rm=na.rm)
+ }else{
+ stop("use should be either rec or mat!\n")
+ }
+
+ # print the method
+ if(gregexpr("p",method)[[1]][1] == 1){
+ p.method <- "Pearson"
+ }else if(gregexpr("s",method)[[1]][1] == 1){
+ p.method <- "Spearman"
+ }else if(gregexpr("k",method)[[1]][1] == 1){
+ p.method <- "Kendall"
+ }else{
+ stop("method should be pearson or spearman or kendall!\n")
+ }
+
+ # sample number
+ n <- dim(na.omit(data.frame(x,y,z)))[1]
+
+ # given variables' number
+ gn <- dim(z)[2]
+
+ # p-value
+ if(p.method == "Kendall"){
+ statistic <- pcor/sqrt(2*(2*(n-gn)+5)/(9*(n-gn)*(n-1-gn)))
+ p.value <- 2*pnorm(-abs(statistic))
+
+ }else{
+ statistic <- pcor*sqrt((n-2-gn)/(1-pcor^2))
+ p.value <- 2*pnorm(-abs(statistic))
+ }
+
+ data.frame(estimate=pcor,p.value=p.value,statistic=statistic,n=n,gn=gn,Method=p.method,Use=p.use)
+}
+
+# By using var-cov matrix
+pcor.mat <- function(x,y,z,method="p",na.rm=T){
+
+ x <- c(x)
+ y <- c(y)
+ z <- as.data.frame(z)
+
+ if(dim(z)[2] == 0){
+ stop("There should be given data\n")
+ }
+
+ data <- data.frame(x,y,z)
+
+ if(na.rm == T){
+ data = na.omit(data)
+ }
+
+ xdata <- na.omit(data.frame(data[,c(1,2)]))
+ Sxx <- cov(xdata,xdata,m=method)
+
+ xzdata <- na.omit(data)
+ xdata <- data.frame(xzdata[,c(1,2)])
+ zdata <- data.frame(xzdata[,-c(1,2)])
+ Sxz <- cov(xdata,zdata,m=method)
+
+ zdata <- na.omit(data.frame(data[,-c(1,2)]))
+ Szz <- cov(zdata,zdata,m=method)
+
+ # is Szz positive definite?
+ zz.ev <- eigen(Szz)$values
+ if(min(zz.ev)[1]<0){
+ stop("\'Szz\' is not positive definite!\n")
+ }
+
+ # partial correlation
+ Sxx.z <- Sxx - Sxz %*% solve(Szz) %*% t(Sxz)
+
+ rxx.z <- cov2cor(Sxx.z)[1,2]
+
+ rxx.z
+}
+
+# By using recursive formula
+pcor.rec <- function(x,y,z,method="p",na.rm=T){
+ #
+
+ x <- c(x)
+ y <- c(y)
+ z <- as.data.frame(z)
+
+ if(dim(z)[2] == 0){
+ stop("There should be given data\n")
+ }
+
+ data <- data.frame(x,y,z)
+
+ if(na.rm == T){
+ data = na.omit(data)
+ }
+
+ # recursive formula
+ if(dim(z)[2] == 1){
+ tdata <- na.omit(data.frame(data[,1],data[,2]))
+ rxy <- cor(tdata[,1],tdata[,2],m=method)
+
+ tdata <- na.omit(data.frame(data[,1],data[,-c(1,2)]))
+ rxz <- cor(tdata[,1],tdata[,2],m=method)
+
+ tdata <- na.omit(data.frame(data[,2],data[,-c(1,2)]))
+ ryz <- cor(tdata[,1],tdata[,2],m=method)
+
+ rxy.z <- (rxy - rxz*ryz)/( sqrt(1-rxz^2)*sqrt(1-ryz^2) )
+
+ return(rxy.z)
+ }else{
+ x <- c(data[,1])
+ y <- c(data[,2])
+ z0 <- c(data[,3])
+ zc <- as.data.frame(data[,-c(1,2,3)])
+
+ rxy.zc <- pcor.rec(x,y,zc,method=method,na.rm=na.rm)
+ rxz0.zc <- pcor.rec(x,z0,zc,method=method,na.rm=na.rm)
+ ryz0.zc <- pcor.rec(y,z0,zc,method=method,na.rm=na.rm)
+
+ rxy.z <- (rxy.zc - rxz0.zc*ryz0.zc)/( sqrt(1-rxz0.zc^2)*sqrt(1-ryz0.zc^2) )
+ return(rxy.z)
+ }
+}
+""")
+
+ R_pcorr_function = rpy2.robjects.r['pcor.test']
+ R_corr_test = rpy2.robjects.r['cor.test']
+
+ primary = rpy2.robjects.FloatVector(range(len(primaryVal)))
+ for i in range(len(primaryVal)):
+ primary[i] = primaryVal[i]
+
+ control = rpy2.robjects.r.matrix(rpy2.robjects.FloatVector( range(len(controlVals)*len(controlVals[0])) ), ncol=len(controlVals))
+ for i in range(len(controlVals)):
+ for j in range(len(controlVals[0])):
+ control[i*len(controlVals[0]) + j] = controlVals[i][j]
+
+ allcorrelations = []
+
+ for targetIndex, oneTargetVals in enumerate(targetVals):
+
+ this_primary = None
+ this_control = None
+ this_target = None
+
+ if None in oneTargetVals:
+
+ goodIndex = []
+ for i in range(len(oneTargetVals)):
+ if oneTargetVals[i] != None:
+ goodIndex.append(i)
+
+ this_primary = rpy2.robjects.FloatVector(range(len(goodIndex)))
+ for i in range(len(goodIndex)):
+ this_primary[i] = primaryVal[goodIndex[i]]
+
+ this_control = rpy2.robjects.r.matrix(rpy2.robjects.FloatVector( range(len(controlVals)*len(goodIndex)) ), ncol=len(controlVals))
+ for i in range(len(controlVals)):
+ for j in range(len(goodIndex)):
+ this_control[i*len(goodIndex) + j] = controlVals[i][goodIndex[j]]
+
+ this_target = rpy2.robjects.FloatVector(range(len(goodIndex)))
+ for i in range(len(goodIndex)):
+ this_target[i] = oneTargetVals[goodIndex[i]]
+
+ else:
+ this_primary = primary
+ this_control = control
+ this_target = rpy2.robjects.FloatVector(range(len(oneTargetVals)))
+ for i in range(len(oneTargetVals)):
+ this_target[i] = oneTargetVals[i]
+
+ one_name = targetNames[targetIndex]
+ one_N = len(this_primary)
+
+ #calculate partial correlation
+ one_pc_coefficient = 'NA'
+ one_pc_p = 1
+
+ try:
+ if method == 's':
+ result = R_pcorr_function(this_primary, this_target, this_control, method='s')
+ else:
+ result = R_pcorr_function(this_primary, this_target, this_control)
+
+ #XZ: In very few cases, the returned coefficient is nan.
+ #XZ: One way to detect nan is to compare the number to itself. NaN is always != NaN
+ if result[0][0] == result[0][0]:
+ one_pc_coefficient = result[0][0]
+ #XZ: when the coefficient value is 1 (primary trait and target trait are the same),
+ #XZ: occationally, the returned p value is nan instead of 0.
+ if result[1][0] == result[1][0]:
+ one_pc_p = result[1][0]
+ elif abs(one_pc_coefficient - 1) < 0.0000001:
+ one_pc_p = 0
+ except:
+ pass
+
+ #calculate zero order correlation
+ one_corr_coefficient = 0
+ one_corr_p = 1
+
+ try:
+ if method == 's':
+ R_result = R_corr_test(this_primary, this_target, method='spearman')
+ else:
+ R_result = R_corr_test(this_primary, this_target)
+
+ one_corr_coefficient = R_result[3][0]
+ one_corr_p = R_result[2][0]
+ except:
+ pass
+
+ traitinfo = [ one_name, one_N, one_pc_coefficient, one_pc_p, one_corr_coefficient, one_corr_p ]
+
+ allcorrelations.append(traitinfo)
+
+ return allcorrelations
+ #End of function compute_partial
+
+
+ allcorrelations = []
+
+ target_trait_number = len(targetVals)
+
+ if target_trait_number < 1000:
+ allcorrelations = compute_partial ( primaryVal, controlVals, targetVals, targetNames, method )
+ else:
+ step = 1000
+ job_number = math.ceil( float(target_trait_number)/step )
+
+ job_targetVals_lists = []
+ job_targetNames_lists = []
+
+ for job_index in range( int(job_number) ):
+ starti = job_index*step
+ endi = min((job_index+1)*step, target_trait_number)
+
+ one_job_targetVals_list = []
+ one_job_targetNames_list = []
+
+ for i in range( starti, endi ):
+ one_job_targetVals_list.append( targetVals[i] )
+ one_job_targetNames_list.append( targetNames[i] )
+
+ job_targetVals_lists.append( one_job_targetVals_list )
+ job_targetNames_lists.append( one_job_targetNames_list )
+
+ ppservers = ()
+ # Creates jobserver with automatically detected number of workers
+ job_server = pp.Server(ppservers=ppservers)
+
+ jobs = []
+ results = []
+
+ for i, one_job_targetVals_list in enumerate( job_targetVals_lists ):
+ one_job_targetNames_list = job_targetNames_lists[i]
+ #pay attention to modules from outside
+ jobs.append( job_server.submit(func=compute_partial, args=( primaryVal, controlVals, one_job_targetVals_list, one_job_targetNames_list, method), depfuncs=(), modules=("rpy2.robjects",)) )
+
+ for one_job in jobs:
+ one_result = one_job()
+ results.append( one_result )
+
+ for one_result in results:
+ for one_traitinfo in one_result:
+ allcorrelations.append( one_traitinfo )
+
+ return allcorrelations
+
+
+
+#XZ, April 30, 2010: The input primaryTrait and targetTrait are instance of webqtlTrait
+#XZ: The primaryTrait and targetTrait should have executed retrieveData function
+def calZeroOrderCorr (primaryTrait, targetTrait, method='pearson'):
+
+ #primaryTrait.retrieveData()
+
+ #there is no None value in primary_val
+ primary_strain, primary_val, primary_var = primaryTrait.exportInformative()
+
+ #targetTrait.retrieveData()
+
+ #there might be None value in target_val
+ target_val = targetTrait.exportData(primary_strain, type="val")
+
+ R_primary = rpy2.robjects.FloatVector(range(len(primary_val)))
+ for i in range(len(primary_val)):
+ R_primary[i] = primary_val[i]
+
+ N = len(target_val)
+
+ if None in target_val:
+ goodIndex = []
+ for i in range(len(target_val)):
+ if target_val[i] != None:
+ goodIndex.append(i)
+
+ N = len(goodIndex)
+
+ R_primary = rpy2.robjects.FloatVector(range(len(goodIndex)))
+ for i in range(len(goodIndex)):
+ R_primary[i] = primary_val[goodIndex[i]]
+
+ R_target = rpy2.robjects.FloatVector(range(len(goodIndex)))
+ for i in range(len(goodIndex)):
+ R_target[i] = target_val[goodIndex[i]]
+
+ else:
+ R_target = rpy2.robjects.FloatVector(range(len(target_val)))
+ for i in range(len(target_val)):
+ R_target[i] = target_val[i]
+
+ R_corr_test = rpy2.robjects.r['cor.test']
+
+ if method == 'spearman':
+ R_result = R_corr_test(R_primary, R_target, method='spearman')
+ else:
+ R_result = R_corr_test(R_primary, R_target)
+
+ corr_result = []
+ corr_result.append( R_result[3][0] )
+ corr_result.append( N )
+ corr_result.append( R_result[2][0] )
+
+ return corr_result
+
+#####################################################################################
+#Input: primaryValue(list): one list of expression values of one probeSet,
+# targetValue(list): one list of expression values of one probeSet,
+# method(string): indicate correlation method ('pearson' or 'spearman')
+#Output: corr_result(list): first item is Correlation Value, second item is tissue number,
+# third item is PValue
+#Function: get correlation value,Tissue quantity ,p value result by using R;
+#Note : This function is special case since both primaryValue and targetValue are from
+#the same dataset. So the length of these two parameters is the same. They are pairs.
+#Also, in the datatable TissueProbeSetData, all Tissue values are loaded based on
+#the same tissue order
+#####################################################################################
+
+def calZeroOrderCorrForTiss (primaryValue=[], targetValue=[], method='pearson'):
+
+ R_primary = rpy2.robjects.FloatVector(range(len(primaryValue)))
+ N = len(primaryValue)
+ for i in range(len(primaryValue)):
+ R_primary[i] = primaryValue[i]
+
+ R_target = rpy2.robjects.FloatVector(range(len(targetValue)))
+ for i in range(len(targetValue)):
+ R_target[i]=targetValue[i]
+
+ R_corr_test = rpy2.robjects.r['cor.test']
+ if method =='spearman':
+ R_result = R_corr_test(R_primary, R_target, method='spearman')
+ else:
+ R_result = R_corr_test(R_primary, R_target)
+
+ corr_result =[]
+ corr_result.append( R_result[3][0])
+ corr_result.append( N )
+ corr_result.append( R_result[2][0])
+
+ return corr_result
+
+
+
+
+def batchCalTissueCorr(primaryTraitValue=[], SymbolValueDict={}, method='pearson'):
+
+ def cal_tissue_corr(primaryTraitValue, oneSymbolValueDict, method ):
+
+ oneSymbolCorrDict = {}
+ oneSymbolPvalueDict = {}
+
+ R_corr_test = rpy2.robjects.r['cor.test']
+
+ R_primary = rpy2.robjects.FloatVector(range(len(primaryTraitValue)))
+
+ for i in range(len(primaryTraitValue)):
+ R_primary[i] = primaryTraitValue[i]
+
+ for (oneTraitSymbol, oneTraitValue) in oneSymbolValueDict.iteritems():
+ R_target = rpy2.robjects.FloatVector(range(len(oneTraitValue)))
+ for i in range(len(oneTraitValue)):
+ R_target[i] = oneTraitValue[i]
+
+ if method =='spearman':
+ R_result = R_corr_test(R_primary, R_target, method='spearman')
+ else:
+ R_result = R_corr_test(R_primary, R_target)
+
+ oneSymbolCorrDict[oneTraitSymbol] = R_result[3][0]
+ oneSymbolPvalueDict[oneTraitSymbol] = R_result[2][0]
+
+ return(oneSymbolCorrDict, oneSymbolPvalueDict)
+
+
+
+ symbolCorrDict = {}
+ symbolPvalueDict = {}
+
+ items_number = len(SymbolValueDict)
+
+ if items_number <= 1000:
+ symbolCorrDict, symbolPvalueDict = cal_tissue_corr(primaryTraitValue, SymbolValueDict, method)
+ else:
+ items_list = SymbolValueDict.items()
+
+ step = 1000
+ job_number = math.ceil( float(items_number)/step )
+
+ job_oneSymbolValueDict_list = []
+
+ for job_index in range( int(job_number) ):
+ starti = job_index*step
+ endi = min((job_index+1)*step, items_number)
+
+ oneSymbolValueDict = {}
+
+ for i in range( starti, endi ):
+ one_item = items_list[i]
+ one_symbol = one_item[0]
+ one_value = one_item[1]
+ oneSymbolValueDict[one_symbol] = one_value
+
+ job_oneSymbolValueDict_list.append( oneSymbolValueDict )
+
+
+ ppservers = ()
+ # Creates jobserver with automatically detected number of workers
+ job_server = pp.Server(ppservers=ppservers)
+
+ jobs = []
+ results = []
+
+ for i, oneSymbolValueDict in enumerate( job_oneSymbolValueDict_list ):
+
+ #pay attention to modules from outside
+ jobs.append( job_server.submit(func=cal_tissue_corr, args=(primaryTraitValue, oneSymbolValueDict, method), depfuncs=(), modules=("rpy2.robjects",)) )
+
+ for one_job in jobs:
+ one_result = one_job()
+ results.append( one_result )
+
+ for one_result in results:
+ oneSymbolCorrDict, oneSymbolPvalueDict = one_result
+ symbolCorrDict.update( oneSymbolCorrDict )
+ symbolPvalueDict.update( oneSymbolPvalueDict )
+
+ return (symbolCorrDict, symbolPvalueDict)
+
+###########################################################################
+#Input: cursor, GeneNameLst (list), TissueProbeSetFreezeId
+#output: geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict (Dict)
+#function: get multi dicts for short and long label functions, and for getSymbolValuePairDict and
+# getGeneSymbolTissueValueDict to build dict to get CorrPvArray
+#Note: If there are multiple probesets for one gene, select the one with highest mean.
+###########################################################################
+def getTissueProbeSetXRefInfo(cursor=None,GeneNameLst=[],TissueProbeSetFreezeId=0):
+ Symbols =""
+ symbolList =[]
+ geneIdDict ={}
+ dataIdDict = {}
+ ChrDict = {}
+ MbDict = {}
+ descDict = {}
+ pTargetDescDict = {}
+
+ count = len(GeneNameLst)
+
+ # Added by NL 01/06/2011
+ # Note that:inner join is necessary in this query to get distinct record in one symbol group with highest mean value
+ # Duo to the limit size of TissueProbeSetFreezeId table in DB, performance of inner join is acceptable.
+ if count==0:
+ query='''
+ select t.Symbol,t.GeneId, t.DataId,t.Chr, t.Mb,t.description,t.Probe_Target_Description
+ from (
+ select Symbol, max(Mean) as maxmean
+ from TissueProbeSetXRef
+ where TissueProbeSetFreezeId=%s and Symbol!='' and Symbol Is Not Null group by Symbol)
+ as x inner join TissueProbeSetXRef as t on t.Symbol = x.Symbol and t.Mean = x.maxmean;
+ '''%TissueProbeSetFreezeId
+
+ else:
+ for i, item in enumerate(GeneNameLst):
+
+ if i == count-1:
+ Symbols += "'%s'" %item
+ else:
+ Symbols += "'%s'," %item
+
+ Symbols = "("+ Symbols+")"
+ query='''
+ select t.Symbol,t.GeneId, t.DataId,t.Chr, t.Mb,t.description,t.Probe_Target_Description
+ from (
+ select Symbol, max(Mean) as maxmean
+ from TissueProbeSetXRef
+ where TissueProbeSetFreezeId=%s and Symbol in %s group by Symbol)
+ as x inner join TissueProbeSetXRef as t on t.Symbol = x.Symbol and t.Mean = x.maxmean;
+ '''% (TissueProbeSetFreezeId,Symbols)
+
+ try:
+
+ cursor.execute(query)
+ results =cursor.fetchall()
+ resultCount = len(results)
+ # Key in all dicts is the lower-cased symbol
+ for i, item in enumerate(results):
+ symbol = item[0]
+ symbolList.append(symbol)
+
+ key =symbol.lower()
+ geneIdDict[key]=item[1]
+ dataIdDict[key]=item[2]
+ ChrDict[key]=item[3]
+ MbDict[key]=item[4]
+ descDict[key]=item[5]
+ pTargetDescDict[key]=item[6]
+
+ except:
+ symbolList = None
+ geneIdDict=None
+ dataIdDict=None
+ ChrDict=None
+ MbDict=None
+ descDict=None
+ pTargetDescDict=None
+
+ return symbolList,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict
+
+###########################################################################
+#Input: cursor, symbolList (list), dataIdDict(Dict)
+#output: symbolValuepairDict (dictionary):one dictionary of Symbol and Value Pair,
+# key is symbol, value is one list of expression values of one probeSet;
+#function: get one dictionary whose key is gene symbol and value is tissue expression data (list type).
+#Attention! All keys are lower case!
+###########################################################################
+def getSymbolValuePairDict(cursor=None,symbolList=None,dataIdDict={}):
+ symbolList = map(string.lower, symbolList)
+ symbolValuepairDict={}
+ valueList=[]
+
+ for key in symbolList:
+ if dataIdDict.has_key(key):
+ DataId = dataIdDict[key]
+
+ valueQuery = "select value from TissueProbeSetData where Id=%s" % DataId
+ try :
+ cursor.execute(valueQuery)
+ valueResults = cursor.fetchall()
+ for item in valueResults:
+ item =item[0]
+ valueList.append(item)
+ symbolValuepairDict[key] = valueList
+ valueList=[]
+ except:
+ symbolValuepairDict[key] = None
+
+ return symbolValuepairDict
+
+
+########################################################################################################
+#input: cursor, symbolList (list), dataIdDict(Dict): key is symbol
+#output: SymbolValuePairDict(dictionary):one dictionary of Symbol and Value Pair.
+# key is symbol, value is one list of expression values of one probeSet.
+#function: wrapper function for getSymbolValuePairDict function
+# build gene symbol list if necessary, cut it into small lists if necessary,
+# then call getSymbolValuePairDict function and merge the results.
+########################################################################################################
+
+def getGeneSymbolTissueValueDict(cursor=None,symbolList=None,dataIdDict={}):
+ limitNum=1000
+ count = len(symbolList)
+
+ SymbolValuePairDict = {}
+
+ if count !=0 and count <=limitNum:
+ SymbolValuePairDict = getSymbolValuePairDict(cursor=cursor,symbolList=symbolList,dataIdDict=dataIdDict)
+
+ elif count >limitNum:
+ SymbolValuePairDict={}
+ n = count/limitNum
+ start =0
+ stop =0
+
+ for i in range(n):
+ stop =limitNum*(i+1)
+ gList1 = symbolList[start:stop]
+ PairDict1 = getSymbolValuePairDict(cursor=cursor,symbolList=gList1,dataIdDict=dataIdDict)
+ start =limitNum*(i+1)
+
+ SymbolValuePairDict.update(PairDict1)
+
+ if stop < count:
+ stop = count
+ gList2 = symbolList[start:stop]
+ PairDict2 = getSymbolValuePairDict(cursor=cursor,symbolList=gList2,dataIdDict=dataIdDict)
+ SymbolValuePairDict.update(PairDict2)
+
+ return SymbolValuePairDict
+
+########################################################################################################
+#input: cursor, GeneNameLst (list), TissueProbeSetFreezeId(int)
+#output: SymbolValuePairDict(dictionary):one dictionary of Symbol and Value Pair.
+# key is symbol, value is one list of expression values of one probeSet.
+#function: wrapper function of getGeneSymbolTissueValueDict function
+# for CorrelationPage.py
+########################################################################################################
+
+def getGeneSymbolTissueValueDictForTrait(cursor=None,GeneNameLst=[],TissueProbeSetFreezeId=0):
+ SymbolValuePairDict={}
+ symbolList,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict = getTissueProbeSetXRefInfo(cursor=cursor,GeneNameLst=GeneNameLst,TissueProbeSetFreezeId=TissueProbeSetFreezeId)
+ if symbolList:
+ SymbolValuePairDict = getGeneSymbolTissueValueDict(cursor=cursor,symbolList=symbolList,dataIdDict=dataIdDict)
+ return SymbolValuePairDict
+
+########################################################################################################
+#Input: cursor(cursor): MySQL connnection cursor;
+# priGeneSymbolList(list): one list of gene symbol;
+# symbolValuepairDict(dictionary): one dictionary of Symbol and Value Pair,
+# key is symbol, value is one list of expression values of one probeSet;
+#Output: corrArray(array): array of Correlation Value,
+# pvArray(array): array of PValue;
+#Function: build corrArray, pvArray for display by calling calculation function:calZeroOrderCorrForTiss
+########################################################################################################
+
+def getCorrPvArray(cursor=None,priGeneSymbolList=[],symbolValuepairDict={}):
+ # setting initial value for corrArray, pvArray equal to 0
+ Num = len(priGeneSymbolList)
+
+ corrArray = [([0] * (Num))[:] for i in range(Num)]
+ pvArray = [([0] * (Num))[:] for i in range(Num)]
+ i = 0
+ for pkey in priGeneSymbolList:
+ j = 0
+ pkey = pkey.strip().lower()# key in symbolValuepairDict is low case
+ if symbolValuepairDict.has_key(pkey):
+ priValue = symbolValuepairDict[pkey]
+ for tkey in priGeneSymbolList:
+ tkey = tkey.strip().lower()# key in symbolValuepairDict is low case
+ if priValue and symbolValuepairDict.has_key(tkey):
+ tarValue = symbolValuepairDict[tkey]
+
+ if tarValue:
+ if i>j:
+ # corrArray stores Pearson Correlation values
+ # pvArray stores Pearson P-Values
+ pcorr_result =calZeroOrderCorrForTiss(primaryValue=priValue,targetValue=tarValue)
+ corrArray[i][j] =pcorr_result[0]
+ pvArray[i][j] =pcorr_result[2]
+ elif i webqtlConfig.MAXCORR:
+ heading = 'Correlation Matrix'
+ detail = ['In order to display Correlation Matrix properly, Do not select more than %d traits for Correlation Matrix.' % webqtlConfig.MAXCORR]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, 7/22/2009: this block is not necessary
+ #elif len(self.searchResult) > 40:
+ # noPCA = 1
+ #else:
+ # noPCA = 0
+
+ traitList = []
+ traitDataList = []
+ for item in self.searchResult:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo()
+ thisTrait.retrieveData(fd.strainlist)
+ traitList.append(thisTrait)
+ traitDataList.append(thisTrait.exportData(fd.strainlist))
+
+ else:
+ heading = 'Correlation Matrix'
+ detail = [HT.Font('Error : ',color='red'),HT.Font('Error occurs while retrieving data FROM database.',color='black')]
+ self.error(heading=heading,detail=detail)
+ return
+
+ NNN = len(traitList)
+
+ if NNN == 0:
+ heading = "Correlation Matrix"
+ detail = ['No trait was selected for %s data set. No matrix generated.' % self.data.RISet]
+ self.error(heading=heading,detail=detail)
+ return
+ elif NNN < 2:
+ heading = 'Correlation Matrix'
+ detail = ['You need to select at least two traits in order to generate correlation matrix.']
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+
+
+
+ corArray = [([0] * (NNN+1))[:] for i in range(NNN+1)]
+ pearsonArray = [([0] * (NNN))[:] for i in range(NNN)]
+ spearmanArray = [([0] * (NNN))[:] for i in range(NNN)]
+ corArray[0][0] = 'Correlation'
+ TD_LR = HT.TD(colspan=2,width="100%",bgColor='#eeeeee')
+ 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':'_','ProbeSetID2':'_','database2':'_','CellID2':'_',
+ 'newNames':fd.formdata.getvalue("newNames", "_"),
+ 'RISet':fd.RISet,'ShowStrains':'ON','ShowLine':'ON', 'rankOrder':'_',
+ "allstrainlist":string.join(fd.strainlist, " "), 'traitList':string.join(self.searchResult, "\t")}
+ if fd.incparentsf1:
+ hddn['incparentsf1']='ON'
+
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ for item in self.searchResult:
+ form.append(HT.Input(name='oldSearchResult', value=str(item), type='hidden'))
+
+ traiturls = []
+ traiturls2 = []
+ shortNames = []
+ verboseNames = []
+ verboseNames2 = []
+ verboseNames3 = []
+ abbreviation = ''
+
+ #dbInfo.ProbeSetID = ProbeSetID
+ #dbInfo.CellID = CellID
+ for i, thisTrait in enumerate(traitList):
+ _url = "javascript:showDatabase2('%s','%s','%s');" % (thisTrait.db.name, thisTrait.name, thisTrait.cellid)
+ #_text = 'Trait%d: ' % (i+1)+str(thisTrait)
+ _text = 'Trait %d: ' % (i+1)+thisTrait.displayName()
+
+ if thisTrait.db.type == 'Geno':
+ _shortName = 'Genotype'
+ abbreviation = 'Genotype'
+ _verboseName = 'Locus %s' % (thisTrait.name)
+ _verboseName2 = 'Chr %s @ %s Mb' % (thisTrait.chr, '%2.3f' % thisTrait.mb)
+ _verboseName3 = ''
+ elif thisTrait.db.type == 'Publish':
+ if thisTrait.post_publication_abbreviation:
+ AbbreviationString = thisTrait.post_publication_abbreviation
+ else:
+ AbbreviationString = ''
+ 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 = ''
+ _shortName = 'Phenotype: %s' % (AbbreviationString)
+ _verboseName2 = ''
+ _verboseName3 = ''
+ if thisTrait.pubmed_id:
+ _verboseName = 'PubMed %d: ' % thisTrait.pubmed_id
+ else:
+ _verboseName = 'Unpublished '
+ _verboseName += 'RecordID/%s' % (thisTrait.name)
+ 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
+ _verboseName2 = 'Phenotype: %s' % (PhenotypeString)
+ if thisTrait.authors:
+ a1 = string.split(thisTrait.authors,',')[0]
+ while a1[0] == '"' or a1[0] == "'" :
+ a1 = a1[1:]
+ _verboseName += ' by '
+ _verboseName += HT.Italic('%s, and colleagues' % (a1))
+ elif thisTrait.db.type == 'Temp':
+ abbreviation = ''
+ _shortName = thisTrait.name
+ if thisTrait.description:
+ _verboseName = thisTrait.description
+ else:
+ _verboseName = 'Temp'
+ _verboseName2 = ''
+ _verboseName3 = ''
+ else:
+ abbreviation = thisTrait.symbol
+ _shortName = 'Symbol: %s ' % thisTrait.symbol
+ _verboseName = thisTrait.symbol
+ _verboseName2 = ''
+ _verboseName3 = ''
+ if thisTrait.chr and thisTrait.mb:
+ _verboseName += ' on Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb)
+ if thisTrait.description:
+ _verboseName2 = '%s' % (thisTrait.description)
+ if thisTrait.probe_target_description:
+ _verboseName3 = '%s' % (thisTrait.probe_target_description)
+
+ cururl = HT.Href(text=_text, url=_url,Class='fs12')
+ cururl2 = HT.Href(text='Trait%d' % (i+1),url=_url,Class='fs12')
+ traiturls.append(cururl)
+ traiturls2.append(cururl2)
+ shortName = HT.Div(id="shortName_" + str(i), style="display:none")
+ shortName.append(_shortName)
+ shortNames.append(shortName)
+ verboseName = HT.Div(id="verboseName_" + str(i), style="display:none")
+ verboseName.append(_verboseName)
+ verboseNames.append(verboseName)
+ verboseName2 = HT.Div(id="verboseName2_" + str(i), style="display:none")
+ verboseName2.append(_verboseName2)
+ verboseNames2.append(verboseName2)
+ verboseName3 = HT.Div(id="verboseName3_" + str(i), style="display:none")
+ verboseName3.append(_verboseName3)
+ verboseNames3.append(verboseName3)
+
+
+
+ corArray[i+1][0] = 'Trait%d: ' % (i+1)+str(thisTrait) + '/' + str(thisTrait) + ': ' + abbreviation + '/' + str(thisTrait) + ': ' + str(_verboseName) + ' : ' + str(_verboseName2) + ' : ' + str(_verboseName3)
+ corArray[0][i+1] = 'Trait%d: ' % (i+1)+str(thisTrait)
+
+ corMatrixHeading = HT.Paragraph('Correlation Matrix', Class="title")
+
+ tbl = HT.TableLite(Class="collap", border=0, cellspacing=1,
+ cellpadding=5, width='100%')
+ row1 = HT.TR(HT.TD(Class="fs14 fwb ffl b1 cw cbrb"),
+ HT.TD('Spearman Rank Correlation (rho)', Class="fs14 fwb ffl b1 cw cbrb", colspan= NNN+1,align="center")
+ )
+ row2 = HT.TR(
+ HT.TD("P e a r s o n r", rowspan= NNN+1,Class="fs14 fwb ffl b1 cw cbrb", width=10,align="center"),
+ HT.TD(Class="b1", width=300))
+ for i in range(NNN):
+ row2.append(HT.TD(traiturls2[i], Class="b1", align="center"))
+ tbl.append(row1,row2)
+
+ nOverlapTrait =9999
+ nnCorr = len(fd.strainlist)
+ for i, thisTrait in enumerate(traitList):
+ newrow = HT.TR()
+ newrow.append(HT.TD(traiturls[i], shortNames[i], verboseNames[i], verboseNames2[i],
+ verboseNames3[i], Class="b1"))
+ names1 = [thisTrait.db.name, thisTrait.name, thisTrait.cellid]
+ for j, thisTrait2 in enumerate(traitList):
+ names2 = [thisTrait2.db.name, thisTrait2.name, thisTrait2.cellid]
+ if j < i:
+ corr,nOverlap = webqtlUtil.calCorrelation(traitDataList[i],traitDataList[j],nnCorr)
+
+ rank = fd.formdata.getvalue("rankOrder", "0")
+
+ if nOverlap < nOverlapTrait:
+ nOverlapTrait = nOverlap
+ if corr > 0.7:
+ fontcolor="red"
+ elif corr > 0.5:
+ fontcolor="#FF6600"
+ elif corr < -0.7:
+ fontcolor="blue"
+ elif corr < -0.5:
+ fontcolor="#009900"
+ else:
+ fontcolor ="#000000"
+
+ pearsonArray[i][j] = corr
+ pearsonArray[j][i] = corr
+ if corr!= 0.0:
+ corArray[i+1][j+1] = '%2.3f/%d' % (corr,nOverlap)
+ thisurl = HT.Href(text=HT.Font('%2.3f'% corr,HT.BR(),'%d' % nOverlap ,color=fontcolor, Class="fs11 fwn"),url = "javascript:showCorrelationPlot2(db='%s',ProbeSetID='%s',CellID='%s',db2='%s',ProbeSetID2='%s',CellID2='%s',rank='%s')" % (names1[0], names1[1], names1[2], names2[0], names2[1], names2[2], rank))
+ else:
+ corArray[i+1][j+1] = '---/%d' % nOverlap
+ thisurl = HT.Font('---',HT.BR(), '%d' % nOverlap)
+
+ newrow.append(HT.TD(thisurl,Class="b1",NOWRAP="ON",align="middle"))
+ elif j == i:
+ corr,nOverlap = webqtlUtil.calCorrelation(traitDataList[i],traitDataList[j],nnCorr)
+ pearsonArray[i][j] = 1.0
+ spearmanArray[i][j] = 1.0
+ corArray[i+1][j+1] = '%2.3f/%d' % (corr,nOverlap)
+ nOverlap = webqtlUtil.calCorrelation(traitDataList[i],traitDataList[j],nnCorr)[1]
+ newrow.append(HT.TD(HT.Href(text=HT.Font(HT.Italic("n"),HT.BR(),str(nOverlap),Class="fs11 fwn b1",align="center", color="000000"), url="javascript:showDatabase2('%s','%s','%s')" % (thisTrait.db.name, thisTrait.name, thisTrait.cellid)), bgColor='#cccccc', align="center", Class="b1", NOWRAP="ON"))
+ else:
+ corr,nOverlap = webqtlUtil.calCorrelationRank(traitDataList[i],traitDataList[j],nnCorr)
+
+ rank = fd.formdata.getvalue("rankOrder", "1")
+
+ if corr > 0.7:
+ fontcolor="red"
+ elif corr > 0.5:
+ fontcolor="#FF6600"
+ elif corr < -0.7:
+ fontcolor="blue"
+ elif corr < -0.5:
+ fontcolor="#009900"
+ else:
+ fontcolor ="#000000"
+ spearmanArray[i][j] = corr
+ spearmanArray[j][i] = corr
+ if corr!= 0.0:
+ corArray[i+1][j+1] = '%2.3f/%d' % (corr,nOverlap)
+ thisurl = HT.Href(text=HT.Font('%2.3f'% corr,HT.BR(),'%d' % nOverlap ,color=fontcolor, Class="fs11 fwn"),url = "javascript:showCorrelationPlot2(db='%s',ProbeSetID='%s',CellID='%s',db2='%s',ProbeSetID2='%s',CellID2='%s',rank='%s')" % (names1[0], names1[1], names1[2], names2[0], names2[1], names2[2], rank))
+ else:
+ corArray[i+1][j+1] = '---/%d' % nOverlap
+ thisurl = HT.Span('---',HT.BR(), '%d' % nOverlap, Class="fs11 fwn")
+ newrow.append(HT.TD(thisurl,Class="b1", NOWRAP="ON",align="middle"))
+ tbl.append(newrow)
+
+ info = HT.Blockquote('Lower left cells list Pearson product-moment correlations; upper right cells list Spearman rank order correlations. Each cell also contains the n of cases. Values higher than 0.7 are displayed in ',HT.Font('red', color='red'),'; those between 0.5 and 0.7 in ',HT.Font('orange', color='#FF6600'),'; Values lower than -0.7 are in ',HT.Font('blue', color='blue'),'; between -0.5 and -0.7 in ',HT.Font('green', color='#009900'),'. Select any cell to generate a scatter plot. Select trait labels for more information.', Class="fs13 fwn")
+
+ exportbutton = HT.Input(type='button', name='export', value='Export', onClick="exportText(allCorrelations);",Class="button")
+ shortButton = HT.Input(type='button' ,name='dispShort',value=' Short Labels ', onClick="displayShortName();",Class="button")
+ verboseButton = HT.Input(type='button' ,name='dispVerbose',value=' Long Labels ', onClick="displayVerboseName();", Class="button")
+ form.append(HT.Blockquote(tbl,HT.P(),shortButton,verboseButton,exportbutton))
+ TD_LR.append(corMatrixHeading,info,form,HT.P())
+
+ #if noPCA:
+ # TD_LR.append(HT.Blockquote('No PCA is computed if more than 32 traits are selected.'))
+
+ #print corArray
+ exportScript = """
+
+
+ """
+ exportScript = exportScript % str(corArray)
+ self.dict['js1'] = exportScript+' '
+ self.dict['body'] = str(TD_LR)
+
+ #don't calculate PCA while number exceed 32
+ #if noPCA:
+ # return
+
+ #XZ, 7/22/2009: deal with PCA stuff
+ #Only for Array Data
+
+ if NNN > 2:
+
+ traitname = map(lambda X:str(X.name), traitList)
+
+ #generate eigenvalues
+
+ # import sys
+ sys.argv=[" "]
+ # import numarray
+ # import numarray.linear_algebra as la
+ #spearmanEigen = eigenvectors(array(spearmanArray))
+ pearsonEigen = la.eigenvectors(numarray.array(pearsonArray))
+ #spearmanEigenValue,spearmanEigenVectors = self.sortEigenVectors(spearmanEigen)
+ pearsonEigenValue,pearsonEigenVectors = self.sortEigenVectors(pearsonEigen)
+
+
+ """
+ for i in range(len(pearsonEigenValue)):
+ if type(pearsonEigenValue[i]).__name__ == 'complex':
+ pearsonEigenValue[i] = pearsonEigenValue[i].real
+ for i in range(len(pearsonEigenVectors)):
+ for j in range(len(pearsonEigenVectors[i])):
+ if type(pearsonEigenVectors[i][j]).__name__ == 'complex':
+ pearsonEigenVectors[i][j] = pearsonEigenVectors[i][j].real
+ if type(pearsonEigenVectors[i][j]).__name__ == 'complex':
+ pearsonEigenVectors[i][j] = pearsonEigenVectors[i][j].real
+ """
+
+ if type(pearsonEigenValue[0]).__name__ == 'complex':
+ pass
+ else:
+ traitHeading = HT.Paragraph('PCA Traits',align='left', Class="title")
+
+ tbl2 = self.calcPCATraits(traitDataList=traitDataList, nnCorr=nnCorr, NNN=NNN, pearsonEigenValue=pearsonEigenValue,
+ pearsonEigenVectors=pearsonEigenVectors, form=form, fd=fd)
+ #Buttons on search page
+ #mintmap = HT.Input(type='button' ,name='mintmap',value='Multiple Mapping', onClick="databaseFunc(this.form,'showIntMap');",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")
+ reset = HT.Input(type='reset',name='',value='Select None',Class="button")
+ updateNames = HT.Input(type='button', name='updateNames',value='Update Trait Names', onClick="editPCAName(this.form);", Class="button")
+ chrMenu = HT.Input(type='hidden',name='chromosomes',value='all')
+
+ """
+ #need to be refined
+ if fd.genotype.Mbmap:
+ scaleMenu = HT.Select(name='scale')
+ scaleMenu.append(tuple(["Genetic Map",'morgan']))
+ scaleMenu.append(tuple(["Physical Map",'physic']))
+ else:
+ scaleMenu = ""
+ """
+
+ tbl2.append(HT.TR(HT.TD(HT.P(),chrMenu,updateNames,selectall,reset,addselect,colspan=3)))
+ form.append(HT.P(),traitHeading,HT.Blockquote(tbl2))
+
+ plotHeading1 = HT.Paragraph('Scree Plot', Class="title")
+ TD_LR.append(plotHeading1)
+ img1 = self.screePlot(NNN=NNN, pearsonEigenValue=pearsonEigenValue)
+
+ TD_LR.append(HT.Blockquote(img1))
+
+ plotHeading2 = HT.Paragraph('Factor Loadings Plot', Class="title")
+ TD_LR.append(plotHeading2)
+ img2 = self.factorLoadingsPlot(pearsonEigenVectors=pearsonEigenVectors, traitList=traitList)
+
+ TD_LR.append(HT.Blockquote(img2))
+
+ self.dict['body'] = str(TD_LR)
+
+ def screePlot(self, NNN=0, pearsonEigenValue=None):
+
+ c1 = pid.PILCanvas(size=(700,500))
+ Plot.plotXY(canvas=c1, dataX=range(1,NNN+1), dataY=pearsonEigenValue, rank=0, labelColor=pid.blue,plotColor=pid.red, symbolColor=pid.blue, XLabel='Factor Number', connectdot=1,YLabel='Percent of Total Variance %', title='Pearson\'s R Scree Plot')
+ filename= webqtlUtil.genRandStr("Scree_")
+ c1.save(webqtlConfig.IMGDIR+filename, format='gif')
+ img=HT.Image('/image/'+filename+'.gif',border=0)
+
+ return img
+
+ def factorLoadingsPlot(self, pearsonEigenVectors=None, traitList=None):
+
+ traitname = map(lambda X:str(X.name), traitList)
+ c2 = pid.PILCanvas(size=(700,500))
+ Plot.plotXY(c2, pearsonEigenVectors[0],pearsonEigenVectors[1], 0, dataLabel = traitname, labelColor=pid.blue, plotColor=pid.red, symbolColor=pid.blue,XLabel='Factor (1)', connectdot=1, YLabel='Factor (2)', title='Factor Loadings Plot (Pearson)', loadingPlot=1)
+ filename= webqtlUtil.genRandStr("FacL_")
+ c2.save(webqtlConfig.IMGDIR+filename, format='gif')
+ img = HT.Image('/image/'+filename+'.gif',border=0)
+
+ return img
+
+ def calcPCATraits(self, traitDataList=None, nnCorr=0, NNN=0, pearsonEigenValue=None, pearsonEigenVectors=None, form=None, fd=None):
+ """
+ This function currently returns the html to be displayed instead of the traits themselves. Need to fix later.
+ """
+
+ detailInfo = string.split(self.searchResult[0],':')
+
+ self.sameProbeSet = 'yes'
+ for item in self.searchResult[1:]:
+ detailInfo2 = string.split(item,':')
+ if detailInfo[0] != detailInfo2[0] or detailInfo[1] != detailInfo2[1]:
+ self.sameProbeSet = None
+ break
+
+ for item in traitDataList:
+ if len(item) != nnCorr:
+ return
+ infoStrains = []
+ infoStrainsPos = []
+ dataArray = [[] for i in range(NNN)]
+
+ for i in range(len(traitDataList[0])):
+ currentStrain = 1
+ for j in range(NNN):
+ if not traitDataList[j][i]:
+ currentStrain = 0
+ break
+ if currentStrain == 1:
+ infoStrains.append(fd.strainlist[i])
+ infoStrainsPos.append(i)
+ for j in range(NNN):
+ dataArray[j].append(traitDataList[j][i])
+
+
+ self.cursor.execute('delete Temp, TempData FROM Temp, TempData WHERE Temp.DataId = TempData.Id and UNIX_TIMESTAMP()-UNIX_TIMESTAMP(CreateTime)>%d;' % webqtlConfig.MAXLIFE)
+
+ StrainIds = []
+ for item in infoStrains:
+ self.cursor.execute('SELECT Strain.Id FROM Strain,StrainXRef, InbredSet WHERE Strain.Name="%s" and Strain.Id = StrainXRef.StrainId and StrainXRef.InbredSetId = InbredSet.Id and InbredSet.Name = "%s"' % (item, fd.RISet))
+ StrainIds.append('%d' % self.cursor.fetchone()[0])
+
+ """
+ #minimal 12 overlapping strains
+ if len(dataArray[0]) < 12:
+ form.append(HT.P(),traitHeading,HT.Blockquote(HT.Paragraph('The number of overlapping strains is less than 12, no PCA scores computed.',align='left')))
+ self.dict['body'] = str(TD_LR)
+ return
+ """
+ dataArray = self.zScore(dataArray)
+ dataArray = numarray.array(dataArray)
+ dataArray2 = numarray.dot(pearsonEigenVectors,dataArray)
+
+ tbl2 = HT.TableLite(cellSpacing=2,cellPadding=0,border=0, width="100%")
+
+ ct0 = time.localtime(time.time())
+ ct = time.strftime("%B/%d %H:%M:%S",ct0)
+ if self.sameProbeSet:
+ newDescription = 'PCA Traits generated at %s from %s' % (ct,detailInfo[1])
+ else:
+ newDescription = 'PCA Traits generated at %s from traits selected' % ct
+
+
+ j = 1
+ self.cursor.execute('SELECT Id FROM InbredSet WHERE Name = "%s"' % fd.RISet)
+ InbredSetId = self.cursor.fetchall()[0][0]
+ user_ip = fd.remote_ip
+ if fd.formdata.getvalue("newNames"):
+ newNames = fd.formdata.getvalue("newNames").split(",")
+ else:
+ newNames = 0
+
+ for item in dataArray2:
+ if pearsonEigenValue[j-1] < 100.0/NNN:
+ break
+
+ if (newNames == 0):
+ description = '%s : PC%02d' % (newDescription, j)
+ else:
+ description = '%s : %s' % (newDescription, newNames[j-1])
+
+ self.cursor.execute('SELECT max(id) FROM TempData')
+ try:
+ DataId = self.cursor.fetchall()[0][0] + 1
+ except:
+ DataId = 1
+ newProbeSetID = webqtlUtil.genRandStr("PCA_Tmp_")
+ self.cursor.execute('insert into Temp(Name,description, createtime,DataId,InbredSetId,IP) values(%s,%s,Now(),%s,%s,%s)' ,(newProbeSetID, description, DataId,InbredSetId,user_ip))
+
+ k = 0
+ for StrainId in StrainIds:
+ self.cursor.execute('insert into TempData(Id, StrainId, value) values(%s,%s,%s)' % (DataId, StrainId, item[k]*(-1.0)))
+ k += 1
+ setDescription = HT.Div(id="pcaTrait%s" % j)
+ descriptionLink = HT.Href(text=description, url="javascript:showDatabase2('Temp','%s','')" % newProbeSetID, Class="fwn")
+ descriptionEdit = HT.Input(type='text', value='', name='editName%s' % j)
+
+ #onBlur='editPDAName(this.form, %s);' % j
+
+ setDescription.append(descriptionLink)
+ setDescription.append(descriptionEdit)
+
+ traitName = "%s:%s" % ('Temp',newProbeSetID)
+ tbl2.append(HT.TR(HT.TD("%d."%j,align="right",valign="top"),HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=traitName),valign="top",width=50),HT.TD(setDescription)))
+ j += 1
+
+ return tbl2
+
+ def zScore(self,dataArray):
+ NN = len(dataArray[0])
+ if NN < 10:
+ return dataArray
+ else:
+ i = 0
+ for data in dataArray:
+ N = len(data)
+ S = reduce(lambda x,y: x+y, data, 0.)
+ SS = reduce(lambda x,y: x+y*y, data, 0.)
+ mean = S/N
+ var = SS - S*S/N
+ stdev = math.sqrt(var/(N-1))
+ data2 = map(lambda x:(x-mean)/stdev,data)
+ dataArray[i] = data2
+ i += 1
+ return dataArray
+
+ def sortEigenVectors(self,vector):
+ try:
+ eigenValues = vector[0].tolist()
+ eigenVectors = vector[1].tolist()
+ combines = []
+ i = 0
+ for item in eigenValues:
+ combines.append([eigenValues[i],eigenVectors[i]])
+ i += 1
+ combines.sort(webqtlUtil.cmpEigenValue)
+ A = []
+ B = []
+ for item in combines:
+ A.append(item[0])
+ B.append(item[1])
+ sum = reduce(lambda x,y: x+y, A, 0.0)
+ A = map(lambda x:x*100.0/sum, A)
+ return [A,B]
+ except:
+ return []
+
diff --git a/web/webqtl/correlationMatrix/TissueAbbreviationPage.py b/web/webqtl/correlationMatrix/TissueAbbreviationPage.py
new file mode 100755
index 00000000..ad8f0ac7
--- /dev/null
+++ b/web/webqtl/correlationMatrix/TissueAbbreviationPage.py
@@ -0,0 +1,79 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2011/12/7
+#
+# Last updated by GeneNetwork Core Team 2011/12/7
+
+
+from base.templatePage import templatePage
+from htmlgen import HTMLgen2 as HT
+
+import string
+import os
+
+
+class TissueAbbreviationPage (templatePage):
+
+ def __init__(self,fd):
+ templatePage.__init__(self, fd)
+
+ shortName=fd.formdata.getfirst("shortTissueName", ',')
+ fullName=fd.formdata.getfirst("fullTissueName", ',')
+ shortNameList=[]
+ fullNameList=[]
+
+ if shortName:
+ shortNameList=shortName.split(',')
+
+ if fullName:
+ fullNameList=fullName.split(',')
+
+ tissueAbbrDict={}
+ for i, item in enumerate(shortNameList):
+ tissueAbbrDict[item]=fullNameList[i]
+
+ if tissueAbbrDict:
+
+ # Creates the table for the fullname and shortname of Tissue
+ tissueAbbrTable = HT.TableLite(border=1, cellspacing=5, cellpadding=3, Class="collap")
+ shortNameList = tissueAbbrDict.keys()
+ shortNameList.sort()
+ abbrHeaderStyle="fs14 fwb ffl"
+ abbrStyle="fs14 fwn ffl"
+
+ tissueAbbrTable.append(HT.TR(HT.TD('Abbr ', Class=abbrHeaderStyle, NOWRAP = 1),HT.TD('Full Name ', Class=abbrHeaderStyle, NOWRAP = 1)))
+ for item in shortNameList:
+ thisTR = HT.TR(HT.TD(item, Class=abbrStyle, NOWRAP = 1))
+ thisTR.append(HT.TD(tissueAbbrDict[item], Class=abbrStyle, NOWRAP = 1))
+
+ tissueAbbrTable.append(thisTR)
+
+ self.dict['body'] = HT.TD(HT.Paragraph("Tissue Abbreviation", Class="title"), HT.Blockquote(tissueAbbrTable))
+ self.dict['title'] = "Tissue Abbreviation"
+ else:
+ heading = "Tissue abbreviation"
+ detail = ["Cannot found Tissue Abbreviation. Please try again later."]
+ self.error(heading=heading,detail=detail)
+ return
+
+
diff --git a/web/webqtl/correlationMatrix/TissueCorrelationPage.py b/web/webqtl/correlationMatrix/TissueCorrelationPage.py
new file mode 100755
index 00000000..7cb86d8c
--- /dev/null
+++ b/web/webqtl/correlationMatrix/TissueCorrelationPage.py
@@ -0,0 +1,673 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+# user can search correlation value and P-Value by inputting one pair gene symbols or multiple gene symbols.
+
+# Created by GeneNetwork Core Team 2010/07/07
+# Last updated by NL, 2011/03/25
+
+from htmlgen import HTMLgen2 as HT
+import os
+import sys
+import time
+import string
+import pyXLWriter as xl
+import cPickle
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from base.webqtlTrait import webqtlTrait
+from correlationMatrix.tissueCorrelationMatrix import tissueCorrelationMatrix
+from utility import webqtlUtil
+from utility.THCell import THCell
+from utility.TDCell import TDCell
+
+
+#########################################
+# Tissue Correlation Page
+#########################################
+
+class TissueCorrelationPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ #read input fields
+ self.action = fd.formdata.getvalue("action", "").strip()
+ self.geneSymbols = fd.formdata.getvalue("geneSymbols","").strip()
+ self.tissueProbeSetFeezeId = fd.formdata.getvalue("tissueProbeSetFeezeId", "").strip()
+ self.recordReturnNum = fd.formdata.getvalue("recordReturnNum", "0").strip()
+ self.calculateMethod = fd.formdata.getvalue("calculateMethod", "0").strip()
+
+ TissueCorrMatrixObject = tissueCorrelationMatrix(tissueProbeSetFreezeId=self.tissueProbeSetFeezeId)
+
+ if not self.geneSymbols:
+ # default page
+
+ Heading = HT.Paragraph("Tissue Correlation", Class="title")
+ Intro = HT.Blockquote("This function computes correlations between transcript expression across different organs and tissues.")
+ Intro.append(HT.BR(),"Select a data set from the pull-down menu and then compute correlations.")
+
+ formName='searchTissueCorrelation'
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), target='_blank',enctype='multipart/form-data', name= formName, submit=HT.Input(type='hidden'))
+ form.append(HT.Input(type="hidden", name="FormID", value=""))
+ form.append(HT.Input(type="hidden", name="action", value="disp"))
+
+ # added by NL 10/12/2010, retreive dataSet info from TissueProbeSetFreeze to get all TissueProbeSetFreezeId, datasetName and FullName
+ tissProbeSetFreezeIds,dataSetNames,dataSetfullNames = TissueCorrMatrixObject.getTissueDataSet()
+
+ dataSetList=[]
+ for i in range(len(tissProbeSetFreezeIds)):
+ dataSetList.append((dataSetfullNames[i], tissProbeSetFreezeIds[i]))
+ dataSetMenu = HT.Select(dataSetList,name="tissueProbeSetFeezeId")
+
+ InfoFile =HT.Input(type="button", Class="button", value=" Info ", onClick="tissueDatasetInfo(this.form.tissueProbeSetFeezeId,%s);"%(dataSetNames))
+ form.append(HT.Strong(" "),dataSetMenu,InfoFile,HT.BR());
+
+ form.append(HT.BR(),HT.Strong(" Please enter only one gene symbol/ENTREZ gene Id per line."),HT.BR(),HT.Strong(" "),HT.Textarea(name="geneSymbols", rows=10, cols=50, text=""),HT.BR(),HT.BR())
+ # calculate method radio button
+ calculateMethodMenu =HT.Input(type="radio", name="calculateMethod", value="0", checked="checked")
+ calculateMethodMenu1 =HT.Input(type="radio", name="calculateMethod", value="1")
+ # record Return method dropdown menu
+ recordReturnMenu = HT.Select(name="recordReturnNum")
+ recordReturnMenu.append(('Top 100','0'))
+ recordReturnMenu.append(('Top 200','1'))
+ recordReturnMenu.append(('Top 500','2'))
+ recordReturnMenu.append(('Top 1000','3'))
+ recordReturnMenu.append(('Top 2000','4'))
+ recordReturnMenu.append(('All','5'))
+
+ # working for input symbol has only one;
+ form.append(HT.Strong(" "),HT.Span("Return:", Class="ffl fwb fs12"),HT.Strong(" "),recordReturnMenu,HT.BR());
+ form.append(HT.BR(),HT.Strong(" "),'Pearson',calculateMethodMenu," "*3,'Spearman Rank',calculateMethodMenu1,HT.BR(),HT.BR());
+ form.append(HT.Strong(" "),HT.Input(type="button", value=" Compute ", Class="button",onClick="selectFormIdForTissueCorr('%s');"%formName))
+ form.append(HT.Strong(" "),HT.Input(type="button", Class="button", value=" Make Default ", onClick = "makeTissueCorrDefault(this.form);"))
+
+ TD_LR = HT.TD(height=200,width="100%",bgcolor='#eeeeee',align="left")
+ TD_LR.append(Heading,Intro,form)
+ self.content_type = 'text/html'
+ self.dict['js1'] = ' '
+ # get tissueProbesetFreezeId from cookie
+ self.dict['js2'] = 'onload ="getTissueCorrDefault(\'searchTissueCorrelation\');"'
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = "Tissue Correlation"
+ elif self.action == 'disp':
+ TissueCount =TissueCorrMatrixObject.getTissueCountofCurrentDataset()
+
+ # add by NL for first Note part in the tissue correlation page. 2010-12-23
+ note =""
+ dataSetName=""
+ datasetFullName=""
+ dataSetName, datasetFullName= TissueCorrMatrixObject.getFullnameofCurrentDataset()
+
+ noteURL = "../dbdoc/"+ dataSetName+".html"
+ noteText = " was used to compute expression correlation across %s samples of tissues and organs. ["%TissueCount
+ # dataset download
+ datasetURL = "../dbdoc/"+ dataSetName+".xls"
+ datasetDownload =HT.Href(text="Download experiment data",url=datasetURL,Class='fs13',target="_blank")
+ note = HT.Blockquote(HT.Href(text=datasetFullName,url=noteURL,Class='fs13',target="_blank"),noteText, datasetDownload,"]",HT.BR())
+
+ geneSymbolLst = [] # gene Symbol list
+ geneSymbolLst = TissueCorrMatrixObject.getGeneSymbolLst(self.geneSymbols)
+
+ symbolCount = len(geneSymbolLst)
+ # The input symbol limit is 100.
+ heading = "Tissue Correlation"
+ if symbolCount > 100:
+ detail = ['The Gene symbols you have input are more than 100. Please limit them to 100.']
+ self.error(heading=heading,detail=detail)
+ return
+ elif symbolCount==0:
+ detail = ['No Gene Symbol was input. No Tissue Correlation matrix generated.' ]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ # search result page
+ # The input symbols should be no less than 1.
+ self.content_type = 'text/html'
+ if symbolCount == 1:
+ self.displaySingleSymbolResultPage(primaryGeneSymbol=geneSymbolLst[0],datasetFullName=datasetFullName,tProbeSetFreezeId=self.tissueProbeSetFeezeId, TissueCorrMatrixObject =TissueCorrMatrixObject,recordReturnNum=self.recordReturnNum,method=self.calculateMethod, note=note,TissueCount =TissueCount)
+ else:
+ self.displayMultiSymbolsResultPage(geneSymbolLst=geneSymbolLst, symbolCount=symbolCount, tProbeSetFreezeId=self.tissueProbeSetFeezeId,TissueCorrMatrixObject =TissueCorrMatrixObject,note=note,TissueCount =TissueCount)
+
+ else:
+ heading = "Tissue Correlation"
+ detail = ['There\'s something wrong with input gene symbol(s), or the value of parameter [action] is not right.' ]
+ self.error(heading=heading,detail=detail)
+ return
+#############################
+# functions
+#############################
+
+ # result page when input symbol has only one
+ def displaySingleSymbolResultPage(self,primaryGeneSymbol=None, datasetFullName=None,tProbeSetFreezeId=None, TissueCorrMatrixObject =None,recordReturnNum=None,method=None,note=None,TissueCount =None):
+ formName = webqtlUtil.genRandStr("fm_")
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data',name= formName, submit=HT.Input(type='hidden'))
+ # the following hidden elements are required parameter in Class(PlotCorrelationPage). So we need to define them here.
+ form.append(HT.Input(type="hidden", name="action", value="disp"))
+ form.append(HT.Input(type="hidden", name="FormID", value="dispSingleTissueCorrelation"))
+ form.append(HT.Input(type="hidden", name="X_geneSymbol", value=""))
+ form.append(HT.Input(type="hidden", name="Y_geneSymbol", value=""))
+ form.append(HT.Input(type="hidden", name="ProbeSetID", value=""))
+ # RISet is not using in Tissue correlation, but is a required parameter in Class(PlotCorrelationPage). So we set dummy value(BXD).
+ form.append(HT.Input(type="hidden", name="RISet", value="BXD"))
+ form.append(HT.Input(type="hidden", name="ShowLine", value="1"))
+ form.append(HT.Input(type="hidden", name="TissueProbeSetFreezeId", value=tProbeSetFreezeId))
+ form.append(HT.Input(type="hidden", name="rankOrder", value=0))
+
+ traitList =[]
+ try:
+ symbolCorrDict, symbolPvalueDict = TissueCorrMatrixObject.calculateCorrOfAllTissueTrait(primaryTraitSymbol=primaryGeneSymbol,method=method)
+ except:
+ heading = "Tissue Correlation"
+ detail = ['Please use the official NCBI gene symbol.' ]
+ self.error(heading=heading,detail=detail)
+ return
+
+ symbolList0,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict=TissueCorrMatrixObject.getTissueProbeSetXRefInfo(GeneNameLst=[])
+ # In case, upper case and lower case issue of symbol, mappedByTargetList function will update input geneSymbolLst based on database search result
+ tempPrimaryGeneSymbol =self.mappedByTargetList(primaryList=symbolList0,targetList=[primaryGeneSymbol])
+ primaryGeneSymbol =tempPrimaryGeneSymbol[0]
+
+ returnNum = self.getReturnNum(recordReturnNum)
+ symbolListSorted=[]
+ symbolList=[]
+ # get key(list) of symbolCorrDict(dict) based on sorting symbolCorrDict(dict) by its' value in desc order
+ symbolListSorted=sorted(symbolCorrDict, key=symbolCorrDict.get, reverse=True)
+ symbolList = self.mappedByTargetList(primaryList=symbolList0,targetList=symbolListSorted)
+
+ if returnNum==None:
+ returnNum =len(symbolList0)
+ IntroReturnNum ="All %d "%returnNum
+ else:
+ IntroReturnNum ="The Top %d" %returnNum
+
+ symbolList = symbolList[:returnNum]
+
+ pageTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="100%", border=0, align="Left")
+
+ ##############
+ # Excel file #
+ ##############
+ filename= webqtlUtil.genRandStr("Corr_")
+ xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button')
+ # Create a new Excel workbook
+ workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename))
+ headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white")
+ #There are 6 lines of header in this file.
+ worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, datasetName=datasetFullName, returnNumber=returnNum)
+ newrow = 6
+ pageTable.append(HT.TR(HT.TD(xlsUrl,height=40)))
+
+ # get header part of result table and export excel file
+ tblobj = {}
+ tblobj['header'], worksheet = self.getTableHeader( method=method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle)
+ newrow += 1
+
+ # get body part of result table and export excel file
+ tblobj['body'], worksheet = self.getTableBody(symbolCorrDict=symbolCorrDict, symbolPvalueDict=symbolPvalueDict,symbolList=symbolList,geneIdDict=geneIdDict,ChrDict=ChrDict,MbDict=MbDict,descDict=descDict,pTargetDescDict=pTargetDescDict,primarySymbol=primaryGeneSymbol,TissueCount=TissueCount, formName=formName, worksheet=worksheet, newrow=newrow,method=method)
+ workbook.close()
+ # creat object for result table for sort function
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ sortby = ("tissuecorr", "down")
+ div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "1"), Id="sortable")
+
+ if method =="0":
+ IntroMethod="Pearson\'s r "
+ else:
+ IntroMethod="Spearman\'s rho "
+ Intro = HT.Blockquote('%s correlations ranked by the %s are displayed.' % (IntroReturnNum,IntroMethod),
+ ' You can resort this list using the small arrowheads in the top row.')
+ Intro.append(HT.BR(),' Click the correlation values to generate scatter plots. Select the symbol to open NCBI Entrez.')
+
+ pageTable.append(HT.TR(HT.TD(div)))
+ form.append(HT.P(), HT.P(),pageTable)
+ corrHeading = HT.Paragraph('Tissue Correlation Table', Class="title")
+ TD_LR = HT.TD(height=200,width="100%",bgcolor='#eeeeee',align="left")
+ TD_LR.append(corrHeading,note,Intro, form, HT.P())
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['js1'] = ' '
+ self.dict['title'] = 'Tissue Correlation Result'
+
+ return
+
+ # result page when input symbols are more than 1
+ def displayMultiSymbolsResultPage(self, geneSymbolLst=None, symbolCount=None, tProbeSetFreezeId=None,TissueCorrMatrixObject=None,note=None,TissueCount =None):
+
+ formName = webqtlUtil.genRandStr("fm_")
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data',name= formName, submit=HT.Input(type='hidden'))
+ # the following hidden elements are required parameter in Class(PlotCorrelationPage). So we need to define them here.
+ form.append(HT.Input(type="hidden", name="action", value="disp"))
+ form.append(HT.Input(type="hidden", name="FormID", value="dispMultiTissueCorrelation"))
+ form.append(HT.Input(type="hidden", name="X_geneSymbol", value=""))
+ form.append(HT.Input(type="hidden", name="Y_geneSymbol", value=""))
+ form.append(HT.Input(type="hidden", name="ProbeSetID", value=""))
+ # RISet is not using in Tissue correlation, but is a required parameter in Class(PlotCorrelationPage). So we set dummy value(BXD).
+ form.append(HT.Input(type="hidden", name="RISet", value="BXD"))
+ form.append(HT.Input(type="hidden", name="ShowLine", value="1"))
+ form.append(HT.Input(type="hidden", name="TissueProbeSetFreezeId", value=tProbeSetFreezeId))
+ form.append(HT.Input(type="hidden", name="rankOrder", value=0))
+
+ # updated by NL, 2011-01-06, build multi list for later use to descrease access to db again
+ symbolList,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict = TissueCorrMatrixObject.getTissueProbeSetXRefInfo(GeneNameLst=geneSymbolLst)
+ # In case, upper case and lower case issue of symbol, mappedByTargetList function will update input geneSymbolLst based on database search result
+ geneSymbolLst =self.mappedByTargetList(primaryList=symbolList,targetList=geneSymbolLst)
+
+ # Added by NL, 2011-01-06, get all shortNames, verboseNames, verboseNames2, verboseNames3, exportArray
+ # for Short Label, Long Label, Export functions
+ geneIdLst,shortNames, verboseNames, verboseNames2, verboseNames3, exportArray = self.getAllLabelsInfo(geneSymbolList =geneSymbolLst, geneIdDict=geneIdDict,ChrDict=ChrDict, MbDict=MbDict, descDict=descDict, pTargetDescDict=pTargetDescDict)
+
+ heading = "Tissue Correlation Matrix"
+
+ #get correlation value and p value based on Gene Symbols list, and return the values in corrArray and pvArray seperately
+ corrArray,pvArray = TissueCorrMatrixObject.getTissueCorrPvArray(geneNameLst=geneSymbolLst,dataIdDict=dataIdDict)
+
+ # in the matrix table, top right corner displays Spearman Rank Correlation's Values and P-Values for each pair of geneSymbols;
+ # left bottom displays Pearson Correlation values and P-Vlues for each pair of geneSymbols.
+ tissueCorrMatrixHeading = HT.Paragraph(heading,Class="title")
+ tcmTable = HT.TableLite(Class="collap", border=0, cellspacing=1, cellpadding=5, width='100%')
+ row1 = HT.TR(HT.TD(Class="fs14 fwb ffl b1 cw cbrb"),HT.TD('Spearman Rank Correlation (rho)' , Class="fs14 fwb ffl b1 cw cbrb", colspan= symbolCount+2,align="center"))
+ col1 = HT.TR(HT.TD("P e a r s o n r", rowspan= symbolCount+1,Class="fs14 fwb ffl b1 cw cbrb", width=10,align="center"),HT.TD("Gene Symbol",Class="fs13 fwb cb b1", width=300))
+ for i in range(symbolCount):
+ GeneSymbol=geneSymbolLst[i].strip()
+ geneId = geneIdLst[i]
+
+ if geneId!=0:
+ _url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % geneId
+ curURL = HT.Href(text=GeneSymbol,url=_url,Class='fs13',target="_blank")
+ else:
+ curURL = GeneSymbol
+ col1.append(HT.TD(curURL,Class="b1", align="center"))
+
+ tcmTable.append(row1,col1)
+ # to decide to whether to show note for "*" or not
+ flag = 0
+ for i in range(symbolCount):
+ GeneSymbol=geneSymbolLst[i].strip()
+ geneId = geneIdLst[i]
+
+ newrow = HT.TR()
+ newrow.append(HT.Input(name="Symbol", value=GeneSymbol, type='hidden'))
+
+ if geneId!=0:
+ _url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" %geneId
+ geneIdURL = HT.Href(text="%s "%GeneSymbol,url=_url,Class="b1",target="_blank")
+ else:
+ # flag =1 will show note for "*"
+ flag = 1
+ geneIdURL =HT.Italic("%s"%GeneSymbol,HT.Font('*', color='red'))
+ newrow.append(HT.TD(geneIdURL,shortNames[i],verboseNames[i],verboseNames2[i],verboseNames3[i], Class="b1", align="left",NOWRAP="ON"))
+
+ for j in range(symbolCount):
+ GeneSymbol2=geneSymbolLst[j].strip()
+ corr = corrArray[i][j]
+ pValue = pvArray[i][j]
+ Color=''
+
+ if j==i:
+ newrow.append(HT.TD(HT.Font(HT.Italic("n"),HT.BR(),str(TissueCount),Class="fs11 fwn b1",align="center", color="000000"), bgColor='#cccccc', align="center", Class="b1", NOWRAP="ON"))
+ exportArray[i+1][j+1] = '%d/%d' % (TissueCount,TissueCount)
+ else:
+ if corr:
+ corr = float(corr)
+ tCorr = "%2.3f" % corr
+ pValue = float(pValue)
+ tPV = "%2.3f" % pValue
+
+ # updated by NL, based on Rob's requirement: delete p value, 2010-02-14
+ # set color for cells by correlationValue
+ if corr > 0.7:
+ fontcolor="red"
+ elif corr > 0.5:
+ fontcolor="#FF6600"
+ elif corr < -0.7:
+ fontcolor="blue"
+ elif corr < -0.5:
+ fontcolor="#009900"
+ else:
+ fontcolor ="#000000"
+
+ # set label for cells
+ # if rank is equal to 0, pearson correlation plot will be the first one;
+ # if rank is equal to 1, spearman ran correlation plot will be the first one.
+ if j>i:
+ exportArray[i+1][j+1] =tCorr+"/"+tPV
+ rank =1
+ elif j
+ var allCorrelations = %s;
+
+ """
+ exportScript = exportScript % str(exportArray)
+ self.dict['js1'] = exportScript+' '
+
+ TD_LR = HT.TD(colspan=2,width="100%",bgcolor="#eeeeee")
+ TD_LR.append(tissueCorrMatrixHeading,note,Intro,form,HT.P())
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = 'Tissue Correlation Result'
+ return
+
+ # Added by NL, 2011-01-06, get all shortNames, verboseNames, verboseNames2, verboseNames3, exportArray
+ # for Short Label, Long Label, Export functions
+ def getAllLabelsInfo(self, geneSymbolList=None,geneIdDict=None,ChrDict=None,MbDict=None,descDict=None,pTargetDescDict=None):
+
+ symbolCount= len(geneSymbolList)
+ geneIdLst =[]
+ exportArray = [([0] * (symbolCount+1))[:] for i in range(symbolCount+1)]
+ exportArray[0][0] = 'Tissue Correlation'
+ shortNames = []
+ verboseNames = []
+ verboseNames2 = []
+ verboseNames3 = []
+
+ # added by NL, 2010-12-21, build DIV and array for short label, long label and export functions
+ for i, geneSymbolItem in enumerate(geneSymbolList):
+ geneSymbol =geneSymbolItem.lower()
+ _shortName =HT.Italic("%s" %geneSymbolItem)
+ _verboseName =''
+ _verboseName2 = ''
+ _verboseName3 = ''
+ if geneIdDict.has_key(geneSymbol):
+ geneIdLst.append(geneIdDict[geneSymbol])
+ else:
+ geneIdLst.append(0)
+ if ChrDict.has_key(geneSymbol) and MbDict.has_key(geneSymbol):
+ _verboseName = ' on Chr %s @ %s Mb' % (ChrDict[geneSymbol],MbDict[geneSymbol])
+ if descDict.has_key(geneSymbol):
+ _verboseName2 = '%s' % (descDict[geneSymbol])
+ if pTargetDescDict.has_key(geneSymbol):
+ _verboseName3 = '%s' % (pTargetDescDict[geneSymbol])
+
+ shortName = HT.Div(id="shortName_" + str(i), style="display:none")
+ shortName.append('Symbol: ')
+ shortName.append(_shortName)
+ shortNames.append(shortName)
+
+ verboseName = HT.Div(id="verboseName_" + str(i), style="display:none")
+ verboseName.append(_shortName)
+ verboseName.append(_verboseName)
+ verboseNames.append(verboseName)
+ verboseName2 = HT.Div(id="verboseName2_" + str(i), style="display:none")
+ verboseName2.append(_verboseName2)
+ verboseNames2.append(verboseName2)
+ verboseName3 = HT.Div(id="verboseName3_" + str(i), style="display:none")
+ verboseName3.append(_verboseName3)
+ verboseNames3.append(verboseName3)
+
+ # exportTissueText in webqtl.js is using '/' as delimilator; add '/', otherwise the last letter in geneSymbol will missing
+ exportArray[i+1][0] =geneSymbolItem+ '/' + geneSymbolItem + '/' +geneSymbolItem + ':' + str(_verboseName) + ' : ' + str(_verboseName2) + ' : ' + str(_verboseName3)
+ exportArray[0][i+1] =geneSymbolItem+ '/'
+
+ return geneIdLst,shortNames, verboseNames, verboseNames2, verboseNames3, exportArray
+
+
+########################################################################
+# functions for display and download when input symbol has only one #
+########################################################################
+
+ # build header and footer parts for export excel file
+ def createExcelFileWithTitleAndFooter(self, workbook=None, datasetName=None,returnNumber=None):
+
+ worksheet = workbook.add_worksheet()
+ titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray")
+
+ ##Write title Info
+ worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle)
+ worksheet.write([2, 0], "Dataset : %s" % datasetName, titleStyle)
+ worksheet.write([3, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle)
+ worksheet.write([4, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle)
+ worksheet.write([5, 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)
+ #Write footer info
+ worksheet.write([8 + returnNumber, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle)
+ worksheet.write([9 + returnNumber, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle)
+
+ return worksheet
+
+ # build header of table when input symbol has only one
+ def getTableHeader(self, method='0', worksheet=None, newrow=None, headingStyle=None):
+
+ tblobj_header = []
+ exportList=[]
+ header=[]
+ header = [THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0),
+ THCell(HT.TD('Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="symbol", idx=1),
+ THCell(HT.TD('Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="desc", idx=2),
+ THCell(HT.TD('Location',HT.BR(),'Chr and Mb ', Class="fs13 fwb ffl b1 cw cbrb"), text="location", idx=3),
+ THCell(HT.TD('N Cases',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), text="nstr", idx=4)]
+ if method =="0":# Pearson Correlation
+ header.append( THCell(HT.TD(HT.Href(
+ text = HT.Span(' r ', HT.Sup(' ?', style="color:#f00"),HT.BR(),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuecorr", idx=5))
+ header.append( THCell(HT.TD(HT.Href(
+ text = HT.Span(' p(r) ', HT.Sup(' ?', style="color:#f00"),HT.BR(),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_p_r"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuepvalue", idx=6))
+
+ exportList =[ 'Gene ID', 'Symbol', 'Description', 'Location', 'N Cases', ' r ', ' p(r) ']
+
+ else:# Spearman Correlation
+ header.append( THCell(HT.TD(HT.Href(
+ text = HT.Span(' rho ', HT.Sup(' ?', style="color:#f00"),HT.BR(),HT.BR(), Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuecorr", idx=5))
+ header.append( THCell(HT.TD(HT.Href(
+ text = HT.Span('p(rho)', HT.Sup(' ?', style="color:#f00"),HT.BR(), HT.BR(),Class="fs13 fwb ffl cw"),
+ target = '_blank',
+ url = "/correlationAnnotation.html#tissue_p_rho"),
+ Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="tissuepvalue", idx=6))
+ exportList = ['Gene ID', 'Symbol', 'Description', 'Location', 'N Cases','rho', ' p(rho) ']
+
+ # build header of excel for download function
+ for ncol, item in enumerate(exportList):
+ worksheet.write([newrow, ncol], item, headingStyle)
+ worksheet.set_column([ncol, ncol], 2*len(item))
+
+ tblobj_header.append(header)
+
+ return tblobj_header, worksheet
+
+ # build body of table when input symbol has only one
+ def getTableBody(self, symbolCorrDict={}, symbolPvalueDict={},symbolList=[],geneIdDict={},ChrDict={},MbDict={},descDict={},pTargetDescDict={},primarySymbol=None, TissueCount=None,formName=None, worksheet=None, newrow=None,method="0"):
+
+ tblobj_body = []
+
+ for symbolItem in symbolList:
+ symbol =symbolItem.lower()
+ if symbol:
+ pass
+ else:
+ symbol ="N/A"
+
+ if geneIdDict.has_key(symbol) and geneIdDict[symbol]:
+ geneId = geneIdDict[symbol]
+ ncbiUrl = HT.Href(text="NCBI",target='_blank',url=webqtlConfig.NCBI_LOCUSID % geneIdDict[symbol], Class="fs10 fwn")
+ else:
+ geneId ="N/A"
+ symbolItem =symbolItem.replace('"','') # some symbol is saved in ["symbol"]format
+ ncbiUrl = HT.Href(text="NCBI",target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % symbol, Class="fs10 fwn")
+
+ _Species="mouse"
+ similarTraitUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), symbolItem, _Species)
+ gnUrl = HT.Href(text="GN",target='_blank',url=similarTraitUrl, Class="fs10 fwn")
+
+ tr = []
+ # updated by NL, 04/25/2011: add checkbox and highlight function
+ # first column of table
+ # updated by NL. 12-7-2011
+ tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="tissueResult",value=symbol, onClick="highlight(this)"), align='right',Class="fs12 fwn b1 c222 fsI",nowrap='ON'),symbol,symbol))
+ # updated by NL, 04/26/2011: add GN and NCBI links
+ #gene symbol (symbol column)
+ tr.append(TDCell(HT.TD(HT.Italic(symbolItem), HT.BR(),gnUrl,"  |  ", ncbiUrl, Class="fs12 fwn b1 c222"),symbolItem, symbolItem))
+
+ #description and probe target description(description column)
+ description_string=''
+ if descDict.has_key(symbol):
+ description_string = str(descDict[symbol]).strip()
+ if pTargetDescDict.has_key(symbol):
+ target_string = str(pTargetDescDict[symbol]).strip()
+
+ description_display = ''
+ if len(description_string) > 1 and description_string != 'None':
+ description_display = description_string
+ else:
+ description_display = symbolItem
+
+ 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()
+
+ tr.append(TDCell(HT.TD(description_display, Class="fs12 fwn b1 c222"), description_display, description_display))
+
+ #trait_location_value is used for sorting (location column)
+ trait_location_repr = 'N/A'
+ trait_location_value = 1000000
+
+ if ChrDict.has_key(symbol) and MbDict.has_key(symbol):
+
+ if ChrDict[symbol] and MbDict[symbol]:
+ mb = float(MbDict[symbol])
+ try:
+ trait_location_value = int(ChrDict[symbol])*1000 + mb
+ except:
+ if ChrDict[symbol].upper() == 'X':
+ trait_location_value = 20*1000 + mb
+ else:
+ trait_location_value = ord(str(ChrDict[symbol]).upper()[0])*1000 + mb
+
+ trait_location_repr = 'Chr%s: %.6f' % (ChrDict[symbol], mb )
+ else:
+ trait_location_repr="N/A"
+ trait_location_value ="N/A"
+
+ tr.append(TDCell(HT.TD(trait_location_repr, Class="fs12 fwn b1 c222", nowrap="on"), trait_location_repr, trait_location_value))
+
+ # number of overlaped cases (N Case column)
+ tr.append(TDCell(HT.TD(TissueCount, Class="fs12 fwn ffl b1 c222", align='right'),TissueCount,TissueCount))
+
+ #tissue correlation (Tissue r column)
+ TCorr = 0.0
+ TCorrStr = "N/A"
+ if symbolCorrDict.has_key(symbol):
+ TCorr = symbolCorrDict[symbol]
+ TCorrStr = "%2.3f" % TCorr
+ symbol2 =symbolItem.replace('"','') # some symbol is saved in "symbol" format
+ # add a new parameter rankOrder for js function 'showTissueCorrPlot'
+ rankOrder = int(method)
+ TCorrPlotURL = "javascript:showTissueCorrPlot('%s','%s','%s',%d)" %(formName, primarySymbol, symbol2,rankOrder)
+ tr.append(TDCell(HT.TD(HT.Href(text=TCorrStr, url=TCorrPlotURL, Class="fs12 fwn ff1"), Class="fs12 fwn ff1 b1 c222", align='right'), TCorrStr, abs(TCorr)))
+ else:
+ tr.append(TDCell(HT.TD(TCorrStr, Class="fs12 fwn b1 c222", align='right'), TCorrStr, abs(TCorr)))
+
+ #p value of tissue correlation (Tissue p(r) column)
+ TPValue = 1.0
+ TPValueStr = "N/A"
+ if symbolPvalueDict.has_key(symbol):
+ TPValue = symbolPvalueDict[symbol]
+ #TPValueStr = "%2.3f" % TPValue
+ TPValueStr=webqtlUtil.SciFloat(TPValue)
+ tr.append(TDCell(HT.TD(TPValueStr, Class="fs12 fwn b1 c222", align='right'), TPValueStr, TPValue))
+
+ tblobj_body.append(tr)
+ # build body(records) of excel for download function
+ for ncol, item in enumerate([geneId, symbolItem, description_display, trait_location_repr,TissueCount, TCorr, TPValue]):
+ worksheet.write([newrow, ncol], item)
+
+ newrow += 1
+
+ return tblobj_body, worksheet
+
+
+ # get return number of records when input symbol has only one
+ def getReturnNum(self,recordReturnNum="0"):
+ if recordReturnNum=="0":
+ returnNum=100
+ elif recordReturnNum=="1":
+ returnNum=200
+ elif recordReturnNum=="2":
+ returnNum=500
+ elif recordReturnNum=="3":
+ returnNum=1000
+ elif recordReturnNum=="4":
+ returnNum=2000
+ elif recordReturnNum=="5":
+ returnNum= None
+
+ return returnNum
+
+ # map list based on the order of target List
+ # if item.lower() exist in both lists, then compare the difference of item's original value of two lists
+ # if not equal, then replace the item in targetList by using the item in primaryList(list from database)
+
+ def mappedByTargetList(self,primaryList=[],targetList=[]):
+
+ tempPrimaryList =[x.lower() for x in primaryList]
+ testTargetList =[y.lower() for y in targetList]
+
+ for i, item in enumerate(tempPrimaryList):
+ if item in testTargetList:
+ index = testTargetList.index(item)
+ if primaryList[i]!=targetList[index]:
+ targetList[index]= primaryList[i]
+
+ return targetList
diff --git a/web/webqtl/correlationMatrix/__init__.py b/web/webqtl/correlationMatrix/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/correlationMatrix/tissueCorrelationMatrix.py b/web/webqtl/correlationMatrix/tissueCorrelationMatrix.py
new file mode 100755
index 00000000..23dc14eb
--- /dev/null
+++ b/web/webqtl/correlationMatrix/tissueCorrelationMatrix.py
@@ -0,0 +1,132 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/11/10
+#
+# Last updated by Ning Liu, 2011/01/26
+
+
+#tissueCorrelationMatrix: funciton part for TissueCorrelationPage.py
+from htmlgen import HTMLgen2 as HT
+from correlation import correlationFunction
+from dbFunction import webqtlDatabaseFunction
+import sys
+
+#########################################
+# Tissue Correlation Page
+#########################################
+
+class tissueCorrelationMatrix:
+ def __init__(self,tissueProbeSetFreezeId=None):
+
+ #initialize parameters
+ self.tProbeSetFreezeId = tissueProbeSetFreezeId
+ self.cursor = webqtlDatabaseFunction.getCursor()
+
+
+
+ #retreive dataSet info from database table TissueProbeSetFreeze to get all TissueProbeSetFreezeId(List), Name(List) and FullName(List)
+ def getTissueDataSet(self):
+ tissProbeSetFreezeIds,Names,fullNames = webqtlDatabaseFunction.getTissueDataSet(cursor=self.cursor)
+ return tissProbeSetFreezeIds,Names,fullNames
+
+
+ #retrieve DatasetName, DatasetFullName based on TissueProbeSetFreezeId, return DatasetName(string), DatasetFullName(string)
+ def getFullnameofCurrentDataset(self):
+
+ DatasetName, DatasetFullName =webqtlDatabaseFunction.getDatasetNamesByTissueProbeSetFreezeId(cursor=self.cursor, TissueProbeSetFreezeId=self.tProbeSetFreezeId)
+ return DatasetName, DatasetFullName
+
+
+ #retrieve how many tissue used in the specific dataset based on TissueProbeSetFreezeId, return TissueCount(int)
+ def getTissueCountofCurrentDataset(self):
+
+ TissueCount =webqtlDatabaseFunction.getTissueCountByTissueProbeSetFreezeId(cursor=self.cursor,TissueProbeSetFreezeId=self.tProbeSetFreezeId)
+ return TissueCount
+
+
+
+ #retrieve corrArray(array), pvArray(array) for display by calling calculation function:calZeroOrderCorrForTiss
+ def getTissueCorrPvArray(self,geneNameLst=None,dataIdDict=None):
+ #retrieve SymbolValuePairDict(Dict), dictionary of Symbol and Value Pair.key is symbol, value is one list of expression values of one probeSet
+ symbolValuepairDict =correlationFunction.getGeneSymbolTissueValueDict(cursor=self.cursor,symbolList=geneNameLst,dataIdDict=dataIdDict)
+ corrArray,pvArray = correlationFunction.getCorrPvArray(cursor=self.cursor,priGeneSymbolList=geneNameLst,symbolValuepairDict=symbolValuepairDict)
+ return corrArray,pvArray
+
+
+
+ #retrieve symbolList,geneIdList,dataIdList,ChrList,MbList,descList,pTargetDescList (all are list type) to
+ #get multi lists for short and long label functions, and for getSymbolValuePairDict and
+ #getGeneSymbolTissueValueDict to build dict to get CorrPvArray
+ def getTissueProbeSetXRefInfo(self,GeneNameLst=[]):
+ symbolList,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict =correlationFunction.getTissueProbeSetXRefInfo(cursor=self.cursor,GeneNameLst=GeneNameLst,TissueProbeSetFreezeId=self.tProbeSetFreezeId)
+ return symbolList,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict
+
+
+
+ #retrieve corrArray(array), pvArray(array) for gene symbol pair
+ def getCorrPvArrayForGeneSymbolPair(self,geneNameLst=None):
+ corrArray = None
+ pvArray = None
+
+ if len(geneNameLst) == 2:
+ #retrieve SymbolValuePairDict(Dict), dictionary of Symbol and Value Pair.key is symbol, value is one list of expression values of one probeSet
+ symbolList,geneIdDict,dataIdDict,ChrDict,MbDict,descDict,pTargetDescDict =correlationFunction.getTissueProbeSetXRefInfo(cursor=self.cursor,GeneNameLst=geneNameLst,TissueProbeSetFreezeId=self.tProbeSetFreezeId)
+ symbolValuepairDict =correlationFunction.getGeneSymbolTissueValueDict(cursor=self.cursor,symbolList=geneNameLst,dataIdDict=dataIdDict)
+ corrArray,pvArray = correlationFunction.getCorrPvArray(cursor=self.cursor,priGeneSymbolList=geneNameLst,symbolValuepairDict=symbolValuepairDict)
+
+ return corrArray,pvArray
+
+
+ #retrieve symbolCorrDict(dict), symbolPvalueDict(dict) to get all tissues' correlation value and P value; key is symbol
+ def calculateCorrOfAllTissueTrait(self, primaryTraitSymbol=None, method='0'):
+ symbolCorrDict, symbolPvalueDict = correlationFunction.calculateCorrOfAllTissueTrait(cursor=self.cursor, primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=self.tProbeSetFreezeId,method=method)
+
+ return symbolCorrDict, symbolPvalueDict
+
+ #Translate GeneId to gene symbol and keep the original order.
+ def getGeneSymbolLst(self, geneSymbols=None):
+ geneSymbolLst=[]
+ geneIdLst=[]
+ #split the input string at every occurrence of the delimiter '\r', and return the substrings in an array.
+ tokens=geneSymbols.strip().split('\r')
+
+ #Ning: To keep the original order of input symbols and GeneIds
+ for i in tokens:
+ i=i.strip()
+ if (len(i) >0) and (i not in geneSymbolLst):
+ geneSymbolLst.append(i)
+ # if input includes geneId(s), then put it/them into geneIdLst
+ if i.isdigit():
+ geneIdLst.append(i)
+
+ #Ning: Replace GeneId with symbol if applicable
+ if len(geneIdLst)>0:
+ # if input includes geneId(s), replace geneId by geneSymbol;
+ geneIdSymbolPair =webqtlDatabaseFunction.getGeneIdSymbolPairByGeneId(cursor=self.cursor, geneIdLst =geneIdLst)
+ for geneId in geneIdLst:
+ if geneIdSymbolPair[geneId]:
+ index = geneSymbolLst.index(geneId)
+ geneSymbolLst[index] =geneIdSymbolPair[geneId]
+
+ return geneSymbolLst
+
+
+
diff --git a/web/webqtl/dataSharing/SharingBody.py b/web/webqtl/dataSharing/SharingBody.py
new file mode 100755
index 00000000..4445e0d1
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingBody.py
@@ -0,0 +1,290 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+sharing_body_string = """
+
About the cases used to generate this set of data:
+
%s
+
About the tissue used to generate this set of data:
+
%s
+
About downloading this data set:
+
%s
+
About the array platform:
+
%s
+
About data values and data processing:
+
%s
+
Data source acknowledgment:
+
%s
+
Experiment Type:
+
%s
+
Overall Design:
+
%s
+
Contributor:
+
%s
+
Citation:
+
%s
+
Submission Date:
+
%s
+
Laboratory:
+
%s
+
Samples:
+
%s
+
+
+
+"""
+
+sharinginfoedit_body_string = """
+
%s
+
+
+
+
+
"""
diff --git a/web/webqtl/dataSharing/SharingInfo.py b/web/webqtl/dataSharing/SharingInfo.py
new file mode 100755
index 00000000..10abcefa
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingInfo.py
@@ -0,0 +1,98 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import httplib
+
+from dbFunction import webqtlDatabaseFunction
+import SharingBody
+
+
+#########################################
+# Sharing Info
+#########################################
+class SharingInfo:
+
+ def __init__(self, GN_AccessionId, InfoPageName):
+ self.GN_AccessionId = GN_AccessionId
+ self.InfoPageName = InfoPageName
+
+ def getInfo(self):
+ cursor = webqtlDatabaseFunction.getCursor()
+ if (not cursor):
+ return
+ sql = "select Id, GEO_Series, Status, Title, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Normalization, InbredSet, InfoPageName, DB_Name, Organism_Id, InfoPageTitle, GN_AccesionId, Tissue, AuthorizedUsers, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, Progreso from InfoFiles where "
+ if(self.GN_AccessionId):
+ sql += "GN_AccesionId = %s"
+ cursor.execute(sql, self.GN_AccessionId)
+ elif (self.InfoPageName):
+ sql += "InfoPageName = %s"
+ cursor.execute(sql, self.InfoPageName)
+ else:
+ raise 'No correct parameter found'
+ info = cursor.fetchone()
+ # fetch datasets file list
+ try:
+ conn = httplib.HTTPConnection("atlas.uthsc.edu")
+ conn.request("GET", "/scandatasets.php?GN_AccesionId=%s" % (info[32]))
+ response = conn.getresponse()
+ data = response.read()
+ filelist = data.split()
+ conn.close()
+ except Exception:
+ filelist = []
+ return info, filelist
+
+ def getBody(self, infoupdate=""):
+ info, filelist = self.getInfo()
+ if filelist:
+ htmlfilelist = '
\n'
+ for i in range(len(filelist)):
+ if i%2==0:
+ filename = filelist[i]
+ filesize = filelist[i+1]
+ htmlfilelist += "
"
+ else:
+ htmlfilelist = "Data sets are not available or are not public yet."
+ return SharingBody.sharinginfo_body_string % (info[31], info[32], infoupdate, info[32], info[1], info[3], info[30], info[4], info[27], info[33], info[2], info[23], info[26], info[11], info[15], info[16], info[18], info[19], info[20], info[21], info[22], info[13], info[12], info[14], info[14], htmlfilelist, info[6], info[35], info[36], info[37], info[38], info[39], info[40], info[5], info[7], info[8], info[9], info[10], info[17], info[24])
diff --git a/web/webqtl/dataSharing/SharingInfoAddPage.py b/web/webqtl/dataSharing/SharingInfoAddPage.py
new file mode 100755
index 00000000..8174bf68
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingInfoAddPage.py
@@ -0,0 +1,47 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+import SharingBody
+import SharingInfo
+
+
+#########################################
+# Sharing Info Edit Page
+#########################################
+class SharingInfoAddPage(templatePage):
+
+ def __init__(self, fd=None):
+ templatePage.__init__(self, fd)
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']:
+ pass
+ else:
+ heading = "Adding Info"
+ detail = ["You don't have the permission to add new dataset"]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ self.dict['body'] = SharingBody.sharinginfoedit_body_string % ("Add new dataset", "-1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")
diff --git a/web/webqtl/dataSharing/SharingInfoDeletePage.py b/web/webqtl/dataSharing/SharingInfoDeletePage.py
new file mode 100755
index 00000000..edc0be7d
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingInfoDeletePage.py
@@ -0,0 +1,55 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+import SharingBody
+import SharingInfo
+
+
+#########################################
+# Sharing Info Delete Page
+#########################################
+class SharingInfoDeletePage(templatePage):
+
+ def __init__(self, fd=None):
+ templatePage.__init__(self, fd)
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']:
+ pass
+ else:
+ heading = "Deleting Info"
+ detail = ["You don't have the permission to delete this dataset"]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ cursor = webqtlDatabaseFunction.getCursor()
+ if (not cursor):
+ return
+ GN_AccessionId = fd.formdata.getvalue('GN_AccessionId')
+ sql = "delete from InfoFiles where GN_AccesionId=%s"
+ cursor.execute(sql, GN_AccessionId)
+ re = cursor.fetchone()
+ self.dict['body'] = "Delete dataset info record (GN_AccesionId=%s) successfully." % GN_AccessionId
\ No newline at end of file
diff --git a/web/webqtl/dataSharing/SharingInfoEditPage.py b/web/webqtl/dataSharing/SharingInfoEditPage.py
new file mode 100755
index 00000000..266b8602
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingInfoEditPage.py
@@ -0,0 +1,51 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+import SharingBody
+import SharingInfo
+
+
+#########################################
+# Sharing Info Edit Page
+#########################################
+class SharingInfoEditPage(templatePage):
+
+ def __init__(self, fd=None):
+ templatePage.__init__(self, fd)
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']:
+ pass
+ else:
+ heading = "Editing Info"
+ detail = ["You don't have the permission to edit this dataset"]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ GN_AccessionId = fd.formdata.getvalue('GN_AccessionId')
+ InfoPageName = fd.formdata.getvalue('InfoPageName')
+ sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName)
+ info, filelist = sharingInfoObject.getInfo()
+ self.dict['body'] = SharingBody.sharinginfoedit_body_string % (info[31], info[0], info[11], info[12], info[13], info[14], info[15], info[16], info[17], info[18], info[19], info[20], info[21], info[22], info[6], info[5], info[35], info[36], info[37], info[38], info[39], info[7], info[8], info[9], info[40], info[32], info[31], info[1], info[2], info[3], info[30], info[4], info[10], info[23], info[25], info[33], info[26], info[27], info[28], info[24], info[34], info[41])
diff --git a/web/webqtl/dataSharing/SharingInfoPage.py b/web/webqtl/dataSharing/SharingInfoPage.py
new file mode 100755
index 00000000..230ba2f3
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingInfoPage.py
@@ -0,0 +1,52 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+import SharingBody
+import SharingInfo
+
+
+#########################################
+# Sharing Info Page
+#########################################
+class SharingInfoPage(templatePage):
+
+ def __init__(self, fd=None):
+ templatePage.__init__(self, fd)
+ GN_AccessionId = fd.formdata.getvalue('GN_AccessionId')
+ InfoPageName = fd.formdata.getvalue('InfoPageName')
+ cursor = webqtlDatabaseFunction.getCursor()
+ if InfoPageName and not GN_AccessionId:
+ sql = "select GN_AccesionId from InfoFiles where InfoPageName = %s"
+ cursor.execute(sql, InfoPageName)
+ GN_AccessionId = cursor.fetchone()
+ url = webqtlConfig.CGIDIR + "main.py?FormID=sharinginfo&GN_AccessionId=%s" % GN_AccessionId
+ self.redirection = url
+ else:
+ sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName)
+ self.dict['body'] = sharingInfoObject.getBody(infoupdate="")
diff --git a/web/webqtl/dataSharing/SharingInfoUpdatePage.py b/web/webqtl/dataSharing/SharingInfoUpdatePage.py
new file mode 100755
index 00000000..a70238b9
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingInfoUpdatePage.py
@@ -0,0 +1,109 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import MySQLdb
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+import SharingBody
+import SharingInfo
+
+#########################################
+# Sharing Info Update Page
+#########################################
+class SharingInfoUpdatePage(templatePage):
+
+ def __init__(self, fd=None):
+ templatePage.__init__(self, fd)
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']:
+ pass
+ else:
+ heading = "Editing Info"
+ detail = ["You don't have the permission to modify this file"]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ cursor = webqtlDatabaseFunction.getCursor()
+ if (not cursor):
+ return
+ Id=fd.formdata.getvalue('Id')
+ GN_AccesionId=fd.formdata.getvalue('GN_AccesionId')
+ GEO_Series=fd.formdata.getvalue('GEO_Series')
+ Status=fd.formdata.getvalue('Status')
+ Title=fd.formdata.getvalue('Title')
+ Organism_Id=fd.formdata.getvalue('Organism_Id')
+ Organism=fd.formdata.getvalue('Organism')
+ Experiment_Type =fd.formdata.getvalue('Experiment_Type')
+ Summary=fd.formdata.getvalue('Summary')
+ Overall_Design=fd.formdata.getvalue('Overall_Design')
+ Contributor=fd.formdata.getvalue('Contributor')
+ Citation=fd.formdata.getvalue('Citation')
+ Submission_Date=fd.formdata.getvalue('Submission_Date')
+ Contact_Name=fd.formdata.getvalue('Contact_Name')
+ Emails=fd.formdata.getvalue('Emails')
+ Phone=fd.formdata.getvalue('Phone')
+ URL=fd.formdata.getvalue('URL')
+ Organization_Name=fd.formdata.getvalue('Organization_Name')
+ Department=fd.formdata.getvalue('Department')
+ Laboratory=fd.formdata.getvalue('Laboratory')
+ Street=fd.formdata.getvalue('Street')
+ City=fd.formdata.getvalue('City')
+ State=fd.formdata.getvalue('State')
+ ZIP=fd.formdata.getvalue('ZIP')
+ Country=fd.formdata.getvalue('Country')
+ Platforms=fd.formdata.getvalue('Platforms')
+ Samples=fd.formdata.getvalue('Samples')
+ Species=fd.formdata.getvalue('Species')
+ Tissue=fd.formdata.getvalue('Tissue')
+ Normalization=fd.formdata.getvalue('Normalization')
+ InbredSet=fd.formdata.getvalue('InbredSet')
+ InfoPageName=fd.formdata.getvalue('InfoPageName')
+ InfoPageTitle=fd.formdata.getvalue('InfoPageTitle')
+ About_Cases=fd.formdata.getvalue('About_Cases')
+ About_Tissue=fd.formdata.getvalue('About_Tissue')
+ About_Download=fd.formdata.getvalue('About_Download')
+ About_Array_Platform=fd.formdata.getvalue('About_Array_Platform')
+ About_Data_Values_Processing=fd.formdata.getvalue('About_Data_Values_Processing')
+ Data_Source_Acknowledge=fd.formdata.getvalue('Data_Source_Acknowledge')
+ AuthorizedUsers=fd.formdata.getvalue('AuthorizedUsers')
+ Progress=fd.formdata.getvalue('Progress')
+ if Id=='-1':
+ sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName)
+ info, filelist = sharingInfoObject.getInfo()
+ if info:
+ heading = "Editing Info"
+ detail = ["The new dataset info record is duplicate."]
+ self.error(heading=heading, detail=detail, error="Error")
+ return
+ sql = """INSERT INTO InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s"""
+ cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress]))
+ infoupdate="This record has been succesfully added."
+ else:
+ sql = """UPDATE InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s WHERE Id=%s"""
+ cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress, Id]))
+ infoupdate="This record has been succesfully updated."
+ sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName)
+ self.dict['body'] = sharingInfoObject.getBody(infoupdate=infoupdate)
\ No newline at end of file
diff --git a/web/webqtl/dataSharing/SharingListDataSetPage.py b/web/webqtl/dataSharing/SharingListDataSetPage.py
new file mode 100755
index 00000000..ec90f5f3
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingListDataSetPage.py
@@ -0,0 +1,99 @@
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from htmlgen import HTMLgen2 as HT
+from base import webqtlConfig
+
+from base.templatePage import templatePage
+
+
+#########################################
+# Sharing List DataSet Page
+#########################################
+class SharingListDataSetPage(templatePage):
+
+ def __init__(self, fd=None):
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']:
+ pass
+ else:
+ heading = "Editing Info"
+ detail = ["You don't have the permission to list the datasets"]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ query = """select GN_AccesionId, InfoPageTitle, Progreso from InfoFiles order by GN_AccesionId"""
+ self.cursor.execute(query)
+ result = self.cursor.fetchall()
+
+ heading = HT.Paragraph('Dataset Table', Class="title")
+
+ newrecord = HT.Href(text="New Record", url="/webqtl/main.py?FormID=sharinginfoadd")
+
+ info = "Click the accession id to view the dataset info. Click the dataset name to edit the dataset info."
+
+ datasetTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0, Class="collap", width="100%")
+
+ tableHeaderRow = HT.TR()
+ tableHeaderRow.append(HT.TD("Accession Id", Class='fs14 fwb ffl b1 cw cbrb', align="center"))
+ tableHeaderRow.append(HT.TD("Dataset name", Class='fs14 fwb ffl b1 cw cbrb', align="center"))
+ tableHeaderRow.append(HT.TD("Progress", Class='fs14 fwb ffl b1 cw cbrb', align="center"))
+ tableHeaderRow.append(HT.TD("Operation", Class='fs14 fwb ffl b1 cw cbrb', align="center"))
+ datasetTable.append(tableHeaderRow)
+
+ for one_row in result:
+ Accession_Id, InfoPage_title, Progress = one_row
+ datasetRow = HT.TR()
+ datasetRow.append(HT.TD(HT.Href(text="GN%s" % Accession_Id, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222"))
+ datasetRow.append(HT.TD(HT.Href(text="%s" % InfoPage_title, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222"))
+ datasetRow.append(HT.TD("%s" % Progress, Class='fs12 fwn ffl b1 c222'))
+ operation_edit = HT.Href(text="Edit", url="/webqtl/main.py?FormID=sharinginfoedit&GN_AccessionId=%s" % Accession_Id)
+ operation_delete = HT.Href(text="Delete", onClick="deleteRecord(%s); return false;" % Accession_Id)
+ operation = HT.TD(Class="fs12 fwn b1 c222", align="center")
+ operation.append(operation_edit)
+ operation.append(" ")
+ operation.append(operation_delete)
+ datasetRow.append(operation)
+ datasetTable.append(datasetRow)
+
+ TD_LR.append(heading, HT.P(), newrecord, HT.P(), info, HT.P(), datasetTable)
+
+ js1 = """ """
+ self.dict['js1'] = js1
+ self.dict['body'] = str(TD_LR)
\ No newline at end of file
diff --git a/web/webqtl/dataSharing/SharingPage.py b/web/webqtl/dataSharing/SharingPage.py
new file mode 100755
index 00000000..cf1d9ac3
--- /dev/null
+++ b/web/webqtl/dataSharing/SharingPage.py
@@ -0,0 +1,40 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+import SharingBody
+
+#########################################
+# SharingPage
+#########################################
+
+class SharingPage(templatePage):
+
+ def __init__(self, fd):
+ templatePage.__init__(self, fd)
+ self.dict['title'] = 'GeneNetwork Data Sharing Zone'
+ self.dict['body'] = SharingBody.sharing_body_string
+ self.dict['js2'] = 'onload="javascript:initialDatasetSelection();"'
\ No newline at end of file
diff --git a/web/webqtl/dataSharing/__init__.py b/web/webqtl/dataSharing/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/dbFunction/__init__.py b/web/webqtl/dbFunction/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/dbFunction/webqtlDatabaseFunction.py b/web/webqtl/dbFunction/webqtlDatabaseFunction.py
new file mode 100755
index 00000000..772e0526
--- /dev/null
+++ b/web/webqtl/dbFunction/webqtlDatabaseFunction.py
@@ -0,0 +1,265 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by Xiaodong Zhou 2011/Jan/20
+
+#webqtlDatabaseFunction.py
+#
+#This file consists of various database related functions; the names are generally self-explanatory.
+
+import MySQLdb
+import string
+from base import webqtlConfig
+
+###########################################################################
+#output: cursor instance
+#function: connect to database and return cursor instance
+###########################################################################
+def getCursor():
+ try:
+ con = MySQLdb.Connect(db=webqtlConfig.DB_NAME, host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER, passwd=webqtlConfig.DB_PASSWD)
+ cursor = con.cursor()
+ return cursor
+ except:
+ return None
+
+
+
+###########################################################################
+#input: cursor, groupName (string)
+#output: mappingMethodId (int) info, value will be Null or else
+#function: retrieve mappingMethodId info from InbredSet table
+###########################################################################
+
+def getMappingMethod(cursor=None, groupName=None):
+ cursor.execute("select MappingMethodId from InbredSet where Name= '%s'" % groupName)
+ mappingMethodId = cursor.fetchone()[0]
+ return mappingMethodId
+
+###########################################################################
+#input: cursor, inbredSetId (int), strainId (int)
+#output: isMappingId (bull) info, value will be 0,1,2 or else, 0 or Null means
+# "can not do mapping", >0 means "can do mapping", >1 means "there exsists
+# redundant data, user needs to choose one to do mapping function"
+#function: retrieve isMappingId info from StrainXRef table
+###########################################################################
+
+def isMapping(cursor=None, inbredSetId=None, strainId=None):
+ cursor.execute("select IsMapping from StrainXRef where InbredSetId='%d' and StrainId = '%d'" %(inbredSetId, strainId))
+ isMappingId = cursor.fetchone()[0]
+ return isMappingId
+
+###########################################################################
+#input: cursor, groupName (string)
+#output: all species data info (array), value will be Null or else
+#function: retrieve all species info from Species table
+###########################################################################
+
+def getAllSpecies(cursor=None):
+ cursor.execute("select Id, Name, MenuName, FullName, TaxonomyId,OrderId from Species Order by OrderId")
+ allSpecies = cursor.fetchall()
+ return allSpecies
+
+###########################################################################
+#input: cursor, RISet (string)
+#output: specie's name (string), value will be None or else
+#function: retrieve specie's name info based on RISet
+###########################################################################
+
+def retrieveSpecies(cursor=None, RISet=None):
+ try:
+ cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % RISet)
+ return cursor.fetchone()[0]
+ except:
+ return None
+
+###########################################################################
+#input: cursor, RISet (string)
+#output: specie's Id (string), value will be None or else
+#function: retrieve specie's Id info based on RISet
+###########################################################################
+
+def retrieveSpeciesId(cursor=None, RISet=None):
+ try:
+ cursor.execute("select SpeciesId from InbredSet where Name = '%s'" % RISet)
+ return cursor.fetchone()[0]
+ except:
+ return None
+
+###########################################################################
+# input: cursor
+# output: tissProbeSetFreezeIdList (list),
+# nameList (list),
+# fullNameList (list)
+# function: retrieve all TissueProbeSetFreezeId,Name,FullName info
+# from TissueProbeSetFreeze table.
+# These data will listed in the dropdown menu in the first page of Tissue Correlation
+###########################################################################
+
+def getTissueDataSet(cursor=None):
+ tissProbeSetFreezeIdList=[]
+ nameList =[]
+ fullNameList = []
+
+ query = "select Id,Name,FullName from TissueProbeSetFreeze; "
+ try:
+ cursor.execute(query)
+ result = cursor.fetchall()
+
+ for row in result:
+ tissProbeSetFreezeIdList.append(row[0])
+ nameList.append(row[1])
+ fullNameList.append(row[2])
+ except:
+ return None
+
+ return tissProbeSetFreezeIdList,nameList,fullNameList
+
+###########################################################################
+# input: cursor,GeneSymbol (string), and TissueProbeSetFreezeId (string)
+# output: geneId (string), dataId (string)
+# function: retrieve geneId and DataId from TissueProbeSetXRef table
+###########################################################################
+
+def getGeneIdDataIdForTissueBySymbol(cursor=None, GeneSymbol=None, TissueProbeSetFreezeId= 0):
+ query ="select GeneId, DataId from TissueProbeSetXRef where Symbol = '%s' and TissueProbeSetFreezeId=%s order by Mean desc" %(GeneSymbol,TissueProbeSetFreezeId)
+ try:
+ cursor.execute(query)
+ result = cursor.fetchone()
+ geneId = result[0]
+ dataId = result[1]
+ except:
+ geneId = 0
+ dataId = 0
+
+ return geneId,dataId
+
+###########################################################################
+# input: cursor, TissueProbeSetFreezeId (int)
+# output: chipId (int)
+# function: retrieve chipId from TissueProbeFreeze table
+###########################################################################
+
+def getChipIdByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None):
+ query = "select TissueProbeFreezeId from TissueProbeSetFreeze where Id =%s" % TissueProbeSetFreezeId
+ try:
+ cursor.execute(query)
+ result = cursor.fetchone()
+ TissueProbeFreezeId = result[0]
+ except:
+ TissueProbeFreezeId =0
+
+ query1 = "select ChipId from TissueProbeFreeze where Id =%s" % TissueProbeFreezeId
+ try:
+ cursor.execute(query1)
+ result1 = cursor.fetchone()
+ chipId = result1[0]
+ except:
+ chipId =0
+
+ return chipId
+
+###########################################################################
+# input: cursor, TissueProbeSetFreezeId (int)
+# output: TissueCount (int)
+# function: retrieve how many tissue used in the specific dataset based on TissueProbeSetFreezeId
+###########################################################################
+def getTissueCountByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None):
+ query1 ="select DataId from TissueProbeSetXRef where TissueProbeSetFreezeId =%s limit 1" % TissueProbeSetFreezeId
+ try:
+ cursor.execute(query1)
+ result1 = cursor.fetchone()
+ DataId = result1[0]
+
+ query2 =" select count(*) from TissueProbeSetData where Id=%s" % DataId
+ try:
+ cursor.execute(query2)
+ result2 = cursor.fetchone()
+ TissueCount = result2[0]
+ except:
+ TissueCount =0
+ except:
+ TissueCount =0
+
+ return TissueCount
+
+###########################################################################
+# input: cursor, TissueProbeSetFreezeId (int)
+# output: DatasetName(string),DatasetFullName(string)
+# function: retrieve DatasetName, DatasetFullName based on TissueProbeSetFreezeId
+###########################################################################
+def getDatasetNamesByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None):
+ query ="select Name, FullName from TissueProbeSetFreeze where Id=%s" % TissueProbeSetFreezeId
+ try:
+ cursor.execute(query)
+ result = cursor.fetchone()
+ DatasetName = result[0]
+ DatasetFullName =result[1]
+ except:
+ DatasetName =None
+ DatasetFullName =None
+
+ return DatasetName, DatasetFullName
+
+###########################################################################
+# input: cursor, geneIdLst (list)
+# output: geneIdSymbolPair(dict),key is geneId, value is geneSymbol
+# function: retrieve GeneId, GeneSymbol based on geneId List
+###########################################################################
+def getGeneIdSymbolPairByGeneId(cursor=None, geneIdLst =None):
+ geneIdSymbolPair={}
+ for geneId in geneIdLst:
+ geneIdSymbolPair[geneId]=None
+
+ query ="select GeneId,GeneSymbol from GeneList where GeneId in (%s)" % string.join(geneIdLst, ", ")
+ try:
+ cursor.execute(query)
+ results = cursor.fetchall()
+ for item in results:
+ geneId =item[0]
+ geneSymbol =item[1]
+ geneIdSymbolPair[geneId]=geneSymbol
+ except:
+ geneIdSymbolPair=None
+
+ return geneIdSymbolPair
+
+
+def updateTissueProbesetXRefByProbesetId(cursor=None, probesetId=None):
+ query ="select Symbol,GeneId,Chr,Mb,description, Probe_Target_Description from ProbeSet where Id =%s"%probesetId
+ try:
+ cursor.execute(query)
+ result =cursor.fetchone()
+
+ updateQuery ='''
+ Update TissueProbeSetXRef
+ Set Symbol='%s',GeneId='%s', Chr='%s', Mb='%s', description ='%s',Probe_Target_Description='%s'
+ where ProbesetId=%s
+ '''%(result[0],result[1],result[2],result[3],result[4],result[5],probesetId)
+
+ cursor.execute(updateQuery)
+
+ except:
+ return None
+
\ No newline at end of file
diff --git a/web/webqtl/externalResource/GCATPage.py b/web/webqtl/externalResource/GCATPage.py
new file mode 100755
index 00000000..7e22f168
--- /dev/null
+++ b/web/webqtl/externalResource/GCATPage.py
@@ -0,0 +1,101 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#GCATPage.py
+
+from htmlgen import HTMLgen2 as HT
+
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+
+
+#Implemented by Xiaodong
+class GCATPage(templatePage):
+
+ def __init__(self,fd):
+
+ self.theseTraits = []
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="middle")
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ self.searchResult = fd.formdata.getvalue('searchResult', [])
+ if type("1") == type(self.searchResult):
+ self.searchResult = [self.searchResult]
+
+ for item in self.searchResult:
+ try:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo(QTL=1)
+ if thisTrait.db.type == "ProbeSet":
+ self.theseTraits.append(thisTrait)
+ except:
+ pass
+
+ if self.theseTraits:
+ pass
+ else:
+ templatePage.__init__(self, fd)
+ heading = 'GCAT'
+ detail = ['You need to select at least one microarray trait to submit to GCAT.']
+ self.error(heading=heading,detail=detail)
+ return
+
+ geneSymbolList = self.getGeneSymbolList()
+
+ geneSymbolSet = set(geneSymbolList)
+
+ if ( len(geneSymbolSet) < 500 ):
+ temp = '+'.join(geneSymbolSet)
+ GCATurl = "http://binf1.memphis.edu/gcat/?organism=mouse&subset=all&year=2010&geneInput=%s" % temp
+
+ self.dict['js1'] = """
+
+ """ % GCATurl
+
+ TD_LR.append(HT.Paragraph("Your selection of %d genes is being submitted to GCAT" % len(geneSymbolSet), Class="cr fs16 fwb", align="Center"))
+ else:
+ TD_LR.append(HT.Paragraph("Your selection of %d genes exceeds the limit of 500. Please reduce your gene number to below the limit." % len(geneSymbolSet), Class="cr fs16 fwb", align="Center"))
+
+
+ self.dict['body'] = TD_LR
+
+
+ def getGeneSymbolList(self):
+ geneList = []
+
+ for item in self.theseTraits:
+ item.retrieveInfo()
+ geneList.append(str(item.symbol))
+
+ return geneList
+
+
diff --git a/web/webqtl/externalResource/GoTreePage.py b/web/webqtl/externalResource/GoTreePage.py
new file mode 100755
index 00000000..07144a23
--- /dev/null
+++ b/web/webqtl/externalResource/GoTreePage.py
@@ -0,0 +1,154 @@
+#GoTreePage.py
+
+import string
+from htmlgen import HTMLgen2 as HT
+
+from base import webqtlConfig
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from dbFunction import webqtlDatabaseFunction
+
+
+#########################################
+# GoTree Page
+#########################################
+class GoTreePage(templatePage):
+
+ def __init__(self,fd):
+
+ self.theseTraits = []
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="middle")
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ self.searchResult = fd.formdata.getvalue('searchResult', [])
+ if type("1") == type(self.searchResult):
+ self.searchResult = [self.searchResult]
+
+ #XZ, self.theseTraits holds the "ProbeSet" traits.
+
+ for item in self.searchResult:
+ try:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo(QTL=1)
+ if thisTrait.db.type == "ProbeSet":
+ self.theseTraits.append(thisTrait)
+ except:
+ pass
+
+ if self.theseTraits:
+ pass
+ else:
+ templatePage.__init__(self, fd)
+ heading = 'WebGestalt'
+ detail = ['You need to select at least one microarray trait to submit.']
+ self.error(heading=heading,detail=detail)
+ return
+
+ chipName = self.testChip(fd)
+
+ #XZ, 8/24/2009: the name of arraylist is misleading. It holds the name of traits.
+ arraylist, geneIdList = self.genGeneIdList(fd)
+
+ target_url = "http://bioinfo.vanderbilt.edu/webgestalt/webgestalt.php"
+
+ formWebGestalt = HT.Form(cgi=target_url, enctype='multipart/form-data', name='WebGestalt', submit = HT.Input(type='hidden'))
+
+ id_type = chipName
+
+ hddnWebGestalt = {'id_list':string.join(arraylist, ","),
+ 'id_type':id_type}
+
+ hddnWebGestalt['ref_type'] = hddnWebGestalt['id_type']
+ hddnWebGestalt['analysis_type'] = 'GO'
+ hddnWebGestalt['significancelevel'] = 'Top10'
+ hddnWebGestalt['stat'] = 'Hypergeometric'
+ hddnWebGestalt['mtc'] = 'BH'
+ hddnWebGestalt['min'] = '2'
+ hddnWebGestalt['id_value'] = fd.formdata.getvalue('correlation')
+
+ species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet)
+
+ if species == 'rat':
+ hddnWebGestalt['org'] = 'Rattus norvegicus'
+ elif species == 'human':
+ hddnWebGestalt['org'] = 'Homo sapiens'
+ elif species == 'mouse':
+ hddnWebGestalt['org'] = 'Mus musculus'
+ else:
+ hddnWebGestalt['org'] = ''
+
+ hddnWebGestalt['org'] = hddnWebGestalt['org'].replace(' ','_')
+
+ for key in hddnWebGestalt.keys():
+ formWebGestalt.append(HT.Input(name=key, value=hddnWebGestalt[key], type='hidden'))
+
+ TD_LR.append(formWebGestalt)
+
+ TD_LR.append(HT.Paragraph("Your selection of %d traits is being submitted to GO Tree" % len(self.theseTraits), Class="cr fs16 fwb", align="Center"))
+
+ # updated by NL, moved mixedChipError() to webqtl.js and change it to mixedChipError(methodName)
+ # moved unknownChipError() to webqtl.js and change it to unknownChipError(chipName)
+ if chipName == 'mixed':
+ methodName = "WebGestalt"
+ self.dict['js1'] = """
+
+ """ % methodName
+ elif chipName.find('_NA') > 0:
+ chipName = chipName[0:-3]
+ self.dict['js1'] = """
+
+ """ % chipName
+ else:
+ self.dict['js1'] = """
+
+ """
+
+ self.dict['body'] = TD_LR
+
+ def testChip(self, fd):
+ chipName0 = ""
+
+ for item in self.theseTraits:
+ self.cursor.execute('SELECT GeneChip.GO_tree_value FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % item.db.name)
+ result = self.cursor.fetchone()
+ if result:
+ chipName = result[0]
+ if chipName:
+ if chipName != chipName0:
+ if chipName0:
+ return 'mixed'
+ else:
+ chipName0 = chipName
+ else:
+ pass
+ else:
+ self.cursor.execute('SELECT GeneChip.Name FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % item.db.name)
+ result = self.cursor.fetchone()
+ chipName = '%s_NA' % result[0]
+ return chipName
+ else:
+ self.cursor.execute('SELECT GeneChip.Name FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % item.db.name)
+ result = self.cursor.fetchone()
+ chipName = '%s_NA' % result[0]
+ return chipName
+ return chipName
+
+ def genGeneIdList(self, fd):
+ arrayList = []
+ geneList = []
+ for item in self.theseTraits:
+ arrayList.append(item.name)
+ item.retrieveInfo()
+ geneList.append(str(item.geneid))
+ return arrayList, geneList
+
diff --git a/web/webqtl/externalResource/ODEPage.py b/web/webqtl/externalResource/ODEPage.py
new file mode 100755
index 00000000..f02fe5aa
--- /dev/null
+++ b/web/webqtl/externalResource/ODEPage.py
@@ -0,0 +1,143 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#ODEPage.py
+
+import string
+from htmlgen import HTMLgen2 as HT
+
+from base import webqtlConfig
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from dbFunction import webqtlDatabaseFunction
+
+class ODEPage(templatePage):
+
+ def __init__(self,fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ #XZ, self.theseTraits holds the "ProbeSet" traits.
+ self.theseTraits = []
+
+ self.searchResult = fd.formdata.getvalue('searchResult', [])
+ if type("1") == type(self.searchResult):
+ self.searchResult = [self.searchResult]
+
+ for item in self.searchResult:
+ try:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo(QTL=1)
+ if thisTrait.db.type == "ProbeSet":
+ self.theseTraits.append(thisTrait)
+ except:
+ pass
+
+ if self.theseTraits:
+ pass
+ else:
+ heading = 'ODE'
+ detail = ['You need to select at least one microarray trait to submit.']
+ self.error(heading=heading,detail=detail)
+ return
+
+ chipName = self.getChipName(fd)
+ species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet)
+
+ if species == 'rat':
+ species = 'Rattus norvegicus'
+ elif species == 'human':
+ species = 'Homo sapiens'
+ elif species == 'mouse':
+ species = 'Mus musculus'
+ else:
+ species = ''
+
+ probesetNameList = self.getProbesetNameList(fd)
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="middle")
+
+ formODE = HT.Form(cgi="http://ontologicaldiscovery.org/index.php?action=manage&cmd=importGeneSet", enctype='multipart/form-data', name='formODE', submit = HT.Input(type='hidden'))
+
+ hddnODE = {}
+
+ hddnODE['client'] = 'genenetwork'
+ hddnODE['species'] = species
+ hddnODE['idtype'] = chipName
+ hddnODE['list'] = string.join(probesetNameList, ",")
+
+ for key in hddnODE.keys():
+ formODE.append(HT.Input(name=key, value=hddnODE[key], type='hidden'))
+
+ TD_LR.append(formODE)
+
+ TD_LR.append(HT.Paragraph("Your selections of %d traits is being exported to the ODE" % len(self.theseTraits), Class="cr fs16 fwb", align="Center"))
+ # updated by NL, moved mixedChipError() to webqtl.js and change it to mixedChipError(methodName)
+ if chipName == 'mixed':
+ methodName = "ODE"
+ self.dict['js1'] = """
+
+ """ % methodName
+ else:
+ self.dict['js1'] = """
+
+ """
+
+ self.dict['body'] = TD_LR
+
+
+
+ def getProbesetNameList(self, fd):
+ probesetNameList = []
+
+ for item in self.theseTraits:
+ probesetNameList.append(item.name)
+
+ return probesetNameList
+
+
+
+ def getChipName(self, fd):
+ chipName0 = ""
+ for item in self.theseTraits:
+ self.cursor.execute('SELECT GeneChip.Name FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % item.db.name)
+ chipName = self.cursor.fetchone()[0]
+ if chipName != chipName0:
+ if chipName0:
+ return 'mixed'
+ else:
+ chipName0 = chipName
+ else:
+ pass
+
+ return chipName
diff --git a/web/webqtl/externalResource/__init__.py b/web/webqtl/externalResource/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/geneWiki/AddGeneRIFPage.py b/web/webqtl/geneWiki/AddGeneRIFPage.py
new file mode 100755
index 00000000..0a5038ef
--- /dev/null
+++ b/web/webqtl/geneWiki/AddGeneRIFPage.py
@@ -0,0 +1,635 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+#geneWikiPage.py
+#
+#This one's pretty self-evident from the title. If you use the GeneWiki module, this is what's behind it. -KA
+
+# Xiaodong changed the dependancy structure
+
+import glob
+import re
+import piddle as pid
+from htmlgen import HTMLgen2 as HT
+import os
+import string
+
+from utility import Plot
+from base.templatePage import templatePage
+from base import webqtlConfig
+from utility import webqtlUtil
+
+#########################################
+# Gene Wiki Page
+#########################################
+
+class AddGeneRIFPage(templatePage):
+
+ fields = ['species', 'pubmedid', 'weburl', 'comment', 'email', 'initial', 'genecategory']
+ spliter = "__split__"
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.updMysql():
+ return
+
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']:
+ self.privilege_to_delete_entry = 1
+ self.additional_colspan = 1
+ else:
+ self.privilege_to_delete_entry = 0
+ self.additional_colspan = 0
+
+ #read input fields
+ self.action = fd.formdata.getvalue("action", "disp").strip()
+ self.symbol = fd.formdata.getvalue("symbol", "").strip()
+ self.Id = fd.formdata.getvalue("Id")
+ self.comment = fd.formdata.getvalue("comment", "").strip()
+ self.email = fd.formdata.getvalue("email", "").strip()
+ self.pubmedid = fd.formdata.getvalue("pubmedid", "").strip()
+ self.species = fd.formdata.getvalue("species", "no specific species:0").strip()
+ self.genecategory = fd.formdata.getvalue("genecategory")
+ self.initial = fd.formdata.getvalue("initial", "").strip()
+ self.weburl = fd.formdata.getvalue("weburl", "").strip()
+ self.reason = fd.formdata.getvalue("reason", "").strip()
+
+ #self.dict['title'] = 'Add GeneWiki Entries for %s' % self.symbol
+
+ if not self.symbol:
+ self.content_type = 'text/html'
+ Heading = HT.Paragraph("GeneWiki Entries", Class="title")
+ help1 = HT.Href(url="/GeneWikihelp.html", text=" help document", Class="fwn", target="_blank")
+ Intro = HT.Blockquote("GeneWiki enables you to enrich the annotation of genes and transcripts. Please submit or edit a GeneWiki note (500 characters max) related to a gene, its transcripts, or proteins. When possible include PubMed identifiers or web resource links (URL addresses). Please ensure that the additions will have widespread use. For additional information, check the GeneWiki ", help1, ".")
+
+ Intro.append(HT.P(), "Please enter a gene symbol in the box below and then click submit.")
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='addgenerif',submit=HT.Input(type='hidden'))
+ form.append(HT.Input(type="text", size = 45, maxlength=100, name="symbol"))
+ form.append(HT.Input(type="hidden", name="FormID", value="geneWiki"))
+ form.append(HT.Input(type="submit", name="submit", value="submit", Class="button"))
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top")
+ TD_LR.append(Heading,Intro,HT.Center(form))
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = "Gene Wiki"
+ elif self.action == 'disp':
+ self.content_type = 'text/html'
+ self.dispWikiPage(fd)
+ elif self.action in ('add', 'update'):
+ if self.action == 'update':
+ self.cursor.execute("Select Id from GeneRIF where symbol='%s' and Id = %s and versionId=0" % (self.symbol, self.Id))
+ if not self.cursor.fetchall():
+ print 'Content-type: text/html\n'
+ heading = "Update Entry"
+ detail = ["The Entry cannot be located."]
+ self.error(heading=heading,detail=detail,error="Error")
+ self.write()
+ return
+ else:
+ pass
+ else:
+ pass
+ status = fd.formdata.getvalue('curStatus')
+ if status == 'insertResult':
+ i = self.insertResultPage(fd)
+ if i == 0:
+ self.content_type = 'text/html'
+ self.insertUpdateCheck(fd, "You entered wrong password, Please try again")
+ elif i == 2:
+ #prevent re-submit
+ url = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % self.symbol
+ self.redirection = url
+ return
+ else:
+ self.content_type = 'text/html'
+ pass
+ elif status == 'insertCheck':
+ self.content_type = 'text/html'
+ self.insertUpdateCheck(fd)
+ else:
+ self.content_type = 'text/html'
+ self.insertUpdateForm(fd)
+ elif self.action == 'del':
+ if self.Id:
+ try:
+ self.Id= int(self.Id)
+ self.delRIF()
+ except:
+ pass
+ self.redirection = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % self.symbol
+ return
+ elif self.action == 'history':
+ self.content_type = 'text/html'
+ self.cursor.execute("Select Id from GeneRIF where symbol='%s' and Id = %s and versionId=0" % (self.symbol, self.Id))
+ if not self.cursor.fetchall():
+ heading = "Update Entry"
+ detail = ["The Entry cannot be located."]
+ self.error(heading=heading,detail=detail,error="Error")
+ else:
+ pass
+ self.historyPage(fd)
+ else:
+ self.content_type = 'text/html'
+ pass
+
+ def historyPage(self, fd):
+ self.dict['title'] = "GeneWiki Entry History"
+ title = HT.Paragraph(self.dict['title'], Class= "title")
+
+ subtitle1 = HT.Blockquote("Most Recent Version:", Class="subtitle")
+ self.cursor.execute("select GeneRIF.Id, versionId, symbol, PubMed_ID, Species.Name, comment, createtime, weburl, reason from GeneRIF left Join Species on GeneRIF.SpeciesId = Species.Id Where GeneRIF.Id = %s and versionId = 0" % self.Id)
+ results = self.cursor.fetchone()
+ subtitle1.append(HT.Blockquote(self.genTable(results)))
+
+ subtitle2 = HT.Blockquote("Previous Version:", Class="subtitle")
+ self.cursor.execute("select GeneRIF.Id, versionId, symbol, PubMed_ID, Species.Name, comment, createtime, weburl, reason from GeneRIF Left Join Species on GeneRIF.SpeciesId = Species.Id Where GeneRIF.Id = %s and versionId > 0 order by versionId desc" % self.Id)
+ results = self.cursor.fetchall()
+ if results:
+ for item in results:
+ subtitle2.append(HT.Blockquote(self.genTable(item), HT.P()))
+ else:
+ subtitle2.append(HT.Blockquote("No Previous History"))
+
+ TD_LR = HT.TD(valign="top", bgcolor="#eeeeee")
+
+ TD_LR.append(title, subtitle1, subtitle2)
+ self.dict['body'] = TD_LR
+
+ def genTable(self, results):
+ if not results:
+ return ""
+ Id, versionId, symbol, PubMed_ID, Species_Name, comment, createtime, weburl, reason = results
+ if not Species_Name:
+ Species_Name="no specific species"
+ tbl = HT.TableLite(border=0, cellpadding=5, Class="collap ffv")
+
+ tbl.append(HT.TR(
+ HT.TD("Gene Symbol: ", width = 200, Class="fs13 fwb b1 c222"),
+ HT.TD(self.symbol, width = 600, Class="fs13 b1 c222"),
+ ))
+
+ tbl.append(HT.TR(
+ HT.TD("Species: ", width = 200, Class="fs13 fwb b1 c222"),
+ HT.TD(Species_Name, width = 600, Class="fs13 b1 c222")
+ ))
+ if PubMed_ID:
+ PubMed_ID = PubMed_ID.split()
+ pTD = HT.TD(Class="fs13 b1 c222")
+ for item in PubMed_ID:
+ pTD.append(HT.Href(text=item, target = "_blank",
+ url = webqtlConfig.PUBMEDLINK_URL % item, Class="fwn"), " ")
+ tbl.append(HT.TR(
+ HT.TD("PubMed IDs: ", Class="fs13 fwb b1 c222"),
+ pTD
+ ))
+
+ if weburl:
+ tbl.append(HT.TR(
+ HT.TD("Web URL: ", Class="fs13 fwb b1 c222"),
+ HT.TD(HT.Href(text=weburl, url=weburl, Class='fwn'), Class="fs13 b1 c222")
+ ))
+
+ tbl.append(HT.TR(
+ HT.TD("Entry: ", Class="fs13 fwb b1 c222"),
+ HT.TD(comment, Class="fs13 b1 c222")
+ ))
+
+ self.cursor.execute("select GeneCategory.Name from GeneCategory, GeneRIFXRef where GeneRIFXRef.GeneRIFId = %s and GeneRIFXRef.versionId=%s and GeneRIFXRef.GeneCategoryId = GeneCategory.Id" % (Id, versionId))
+ results = self.cursor.fetchall()
+ if results:
+ tHD = HT.TD(Class="fs13 b1 c222")
+ for i, item in enumerate(results):
+ tHD.append(item[0])
+ if i < len(results)-1:
+ tHD.append("; ")
+ if i%2 == 1:
+ tHD.append(HT.BR())
+
+ tbl.append(HT.TR(
+ HT.TD("Category: ", Class="fs13 fwb b1 c222"),
+ tHD
+ ))
+
+ tbl.append(HT.TR(
+ HT.TD("Add Time: ", Class="fs13 fwb b1 c222"),
+ HT.TD(createtime, Class="fs13 b1 c222")
+ ))
+ if reason:
+ tbl.append(HT.TR(
+ HT.TD("Reason for Modification: ", Class="fs13 fwb b1 c222"),
+ HT.TD(reason, Class="fs13 b1 c222")
+ ))
+ return tbl
+
+ def insertUpdateCheck(self, fd, warning= ""):
+ self.dict['title'] = "%s GeneWiki Entry for %s" % (self.action.title(), self.symbol)
+ #mailsrch = re.compile('([\w\-][\w\-\.]*@[\w\-][\w\-\.]+[a-zA-Z]{1,4})([\s,;])*')
+ mailsrch = re.compile('([\w\-][\w\-\.]*)@([\w\-\.]+)\.([a-zA-Z]{1,4})([\s,;])*')
+ httpsrch = re.compile('((?:http|ftp|gopher|file)://(?:[^ \n\r<\)]+))([\s,;])*')
+ if not self.comment or not self.email:
+ heading = self.dict['title']
+ detail = ["Please don't leave text field or email field empty."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ if self.action == 'update' and not self.reason:
+ heading = self.dict['title']
+ detail = ["Please submit your reason for this modification."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ if len(self.comment) >500:
+ heading = self.dict['title']
+ detail = ["Your entry is more than 500 characters."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+ if self.email and re.sub(mailsrch, "", self.email) != "":
+ heading = self.dict['title']
+ detail = ["The format of your email address is incorrect."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+
+ if self.weburl == "http://":
+ self.weburl = ""
+
+ if self.weburl and re.sub(httpsrch, "", self.weburl) != "":
+ heading = self.dict['title']
+ detail = ["The format of web resource link is incorrect."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+
+ if self.pubmedid:
+ try:
+ test = map(int, string.split(self.pubmedid))
+ except:
+ heading = self.dict['title']
+ detail = ["PubMed IDs can only be integers."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='addgenerif',submit=HT.Input(type='hidden'))
+ recordInfoTable = HT.TableLite(border=0, cellspacing=1, cellpadding=5,align="center")
+
+ addButton = HT.Input(type='submit',name='submit', value='%s GeneWiki Entry' % self.action.title(),Class="button")
+ hddn = {'curStatus':'insertResult', 'FormID':'geneWiki', 'symbol':self.symbol,
+ 'comment':self.comment, 'email':self.email, 'species':self.species,
+ 'action':self.action, 'reason':self.reason}
+ if self.Id:
+ hddn['Id']=self.Id
+
+ formBody = HT.TableLite()
+
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("Species: ")),
+ HT.TD(width=10),
+ HT.TD(string.split(self.species, ":")[0])
+ ))
+ if self.pubmedid:
+ try:
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("PubMed IDs: ")),
+ HT.TD(width=10),
+ HT.TD(self.pubmedid)
+ ))
+ hddn['pubmedid'] = self.pubmedid
+ except:
+ pass
+ if self.weburl:
+ try:
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("Web URL: ")),
+ HT.TD(width=10),
+ HT.TD(HT.Href(text=self.weburl, url=self.weburl, Class='fwn'))
+ ))
+ hddn['weburl'] = self.weburl
+ except:
+ pass
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("Gene Notes: ")),
+ HT.TD(width=10),
+ HT.TD(self.comment)
+ ))
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("Email: ")),
+ HT.TD(width=10),
+ HT.TD(self.email)
+ ))
+ if self.initial:
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("Initial: ")),
+ HT.TD(width=10),
+ HT.TD(self.initial)
+ ))
+ hddn['initial'] = self.initial
+
+ if self.genecategory:
+ cTD = HT.TD()
+ if type(self.genecategory) == type(""):
+ self.genecategory = string.split(self.genecategory)
+ self.cursor.execute("Select Id, Name from GeneCategory where Id in (%s) order by Name " % string.join(self.genecategory, ', '))
+ results = self.cursor.fetchall()
+ for item in results:
+ cTD.append(item[1], HT.BR())
+
+ formBody.append(HT.TR(
+ HT.TD(HT.Strong("Category: ")),
+ HT.TD(width=10),
+ cTD
+ ))
+ hddn['genecategory'] = string.join(self.genecategory, " ")
+
+ formBody.append(HT.TR(
+ HT.TD(
+ HT.BR(), HT.BR(),
+ HT.Div("For security reasons, enter the code (case insensitive) in the image below to finalize your submission"), HT.BR(),
+ addButton, HT.Input(type="password", size = 25, name="password"),
+ colspan=3)
+ ))
+
+
+ code = webqtlUtil.genRandStr(length=5, chars="abcdefghkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789")
+ filename= webqtlUtil.genRandStr("Sec_")
+ hddn['filename'] = filename
+ securityCanvas = pid.PILCanvas(size=(300,100))
+ Plot.plotSecurity(securityCanvas, text=code)
+
+ os.system("touch %s_.%s" % (os.path.join(webqtlConfig.IMGDIR,filename), code))
+ securityCanvas.save(os.path.join(webqtlConfig.IMGDIR,filename), format='png')
+
+ formBody.append(HT.TR(
+ HT.TD(HT.Image("/image/"+filename+".png"), colspan=3)
+ ))
+
+ hddn['filename'] = filename
+ TD_LR = HT.TD(valign="top", bgcolor="#eeeeee")
+ title = HT.Paragraph("%s GeneWiki Entry for %s" % (self.action.title(), self.symbol), Class="title")
+
+ form.append(HT.P(), HT.Blockquote(formBody))
+
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ TD_LR.append(title, HT.Blockquote(warning, Id="red"), form)
+
+ self.dict['body'] = TD_LR
+
+ def insertUpdateForm(self, fd):
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='addgenerif',submit=HT.Input(type='hidden'))
+ addButton = HT.Input(type='submit',name='submit', value='%s GeneWiki Entry' % self.action.title(),Class="button")
+ resetButton = HT.Input(type='reset',Class="button")
+
+ hddn = {'curStatus':'insertCheck', 'FormID':'geneWiki', 'symbol':self.symbol, 'action':self.action, 'reason':self.reason}
+ if self.Id:
+ hddn['Id']=self.Id
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ if self.action == 'update':
+ self.cursor.execute("Select Species.Name, PubMed_ID, weburl, comment, email, initial from GeneRIF left JOIN Species on Species.Id = GeneRIF.SpeciesId where symbol='%s' and GeneRIF.Id = %s and versionId=0" % (self.symbol, self.Id))
+ oldSpeciesId, oldPubMed_ID, oldweburl, oldcomment, oldemail, oldinitial = self.cursor.fetchone()
+ if not oldSpeciesId:
+ oldSpeciesId="no specific species:0"
+ oldemail = ""
+ self.cursor.execute("Select GeneCategoryId from GeneRIFXRef where GeneRIFId = %s and versionId=0" % self.Id)
+ oldCategory = self.cursor.fetchall()
+ if oldCategory:
+ oldCategory = map(lambda X:X[0], oldCategory)
+ else:
+ oldSpeciesId = oldPubMed_ID = oldcomment = oldemail = oldinitial = oldweburl = ""
+ oldCategory= ()
+
+ if not oldweburl:
+ oldweburl = "http://"
+ #############################
+ TD_LR = HT.TD(valign="top", bgcolor="#eeeeee")
+ title = HT.Paragraph("%s GeneWiki Entry for %s" % (self.action.title(), self.symbol), Class="title")
+
+ smenu = HT.Select(name="species")
+ self.cursor.execute("select Id, Name from Species order by Name")
+ for Id, Name in self.cursor.fetchall():
+ smenu.append((Name, "%s:%s" % (Name, Id)))
+ smenu.append(("no specific species", "no specific species:0"))
+ if oldSpeciesId != "":
+ smenu.selected.append(oldSpeciesId)
+ else:
+ smenu.selected.append("mouse")
+ formBody = HT.TableLite()
+
+ if self.action == 'update':
+ formBody.append(HT.TR(
+ HT.TD("Reason for Modification: "),
+ HT.TD(width=10),
+ HT.TD(HT.Input(type="text", size = 45, maxlength=100, name="reason"))
+ ))
+ else:
+ pass
+
+ formBody.append(HT.TR(
+ HT.TD("Species: "),
+ HT.TD(" ", width=10),
+ HT.TD(smenu)
+ ))
+ formBody.append(HT.TR(
+ HT.TD("PubMed IDs: "),
+ HT.TD(" ", width=10),
+ HT.TD(HT.Input(type="text", size = 25, maxlength=25, name="pubmedid", value=oldPubMed_ID), " (optional, separate by blank space only)")
+ ))
+ formBody.append(HT.TR(
+ HT.TD("Web resource URL: "),
+ HT.TD(" ", width=10),
+ HT.TD(HT.Input(type="text", size = 50, maxlength=100, name="weburl", value=oldweburl), " (optional)")
+ ))
+ formBody.append(HT.TR(
+ HT.TD("Text: "),
+ HT.TD(" ", width=10),
+ HT.TD(HT.Textarea(cols = 60, rows=5, name="comment", text=oldcomment))
+ ))
+ formBody.append(HT.TR(
+ HT.TD("Email: "),
+ HT.TD(" ", width=10),
+ HT.TD(HT.Input(type="text", size = 40, maxlength=40, name="email", value=oldemail))
+ ))
+ formBody.append(HT.TR(
+ HT.TD("User Code: "),
+ HT.TD(" ", width=10),
+ HT.TD(HT.Input(type="text", size =15, maxlength=10, name="initial", value=oldinitial), " (optional user or project code or your initials)")
+ ))
+
+ self.cursor.execute("Select Id, Name from GeneCategory order by Name")
+ results = self.cursor.fetchall()
+ if results:
+ tbl2 = HT.TableLite()
+ tempTR = HT.TR()
+ for i, item in enumerate(results):
+ if item[0] in oldCategory:
+ boxchecked = 1
+ else:
+ boxchecked = 0
+ tempTR.append(HT.TD(HT.Input(type='checkbox', Class='checkbox', name='genecategory', value = item[0], checked=boxchecked), valign="top"), HT.TD(" ", item[1], valign="top"))
+ if (i%2):
+ tbl2.append(tempTR)
+ tempTR = HT.TR()
+ tbl2.append(tempTR)
+ formBody.append(HT.TR(
+ HT.TD("Category of Gene Note", HT.BR(), "(Please select one or", HT.BR(), "many categories):"),
+ HT.TD(" ", width=10),
+ HT.TD(tbl2)
+ ))
+ formBody.append(HT.TR(
+ HT.TD(addButton, " "*10, resetButton, colspan=3)
+ ))
+
+ form.append(HT.P(), HT.Blockquote(formBody))
+
+ TD_LR.append(title, form)
+ self.dict['title'] = "%s GeneWiki Entry for %s" % (self.action.title(), self.symbol)
+ self.dict['body'] = TD_LR
+
+ def dispWikiPage(self, fd):
+ addButton = HT.Input(type="button",value="New GeneWiki Entry",onClick= \
+ "openNewWin('%s')" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&action=add&symbol=%s" % self.symbol),
+ Class="button")
+ geneRIFBody = HT.TableLite(cellpadding=3, width="100%")
+ geneRIFBody.append(HT.TR(HT.TD(HT.Paragraph("GeneWiki for %s: " % self.symbol, addButton, Class="subtitle"), colspan=5+self.additional_colspan, height=40)))
+
+ self.cursor.execute("select comment, PubMed_ID, weburl, Id from GeneRIF where symbol = '%s' and display > 0 and versionId=0" % self.symbol)
+ results = self.cursor.fetchall()
+ geneRIFBody.append(HT.TR(HT.TD(), HT.TD("GeneNetwork:", colspan=4+self.additional_colspan, Class="fwb")))
+ if results:
+ for i, item in enumerate(results):
+ PubMedLink = WebLink = comma = ""
+ if item[1]:
+ PubMedLink = HT.Href(text="PubMed", target = "_blank",
+ url = webqtlConfig.PUBMEDLINK_URL % item[1], Class="fwn")
+ if item[2]:
+ if PubMedLink: comma = ", "
+ WebLink = HT.Href(text="URL Link", target = "_blank",
+ url = item[2], Class="fwn")
+ myTR = HT.TR(
+ HT.TD(" ", width=20),
+ HT.TD(HT.Strong(i+1, ". "), valign="top"),
+ HT.TD(HT.Paragraph(item[0], " ", PubMedLink, comma, WebLink), valign="top"),
+ #HT.TD(, width=40, valign="top"),
+ HT.TD(
+ HT.Href(url=os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE)+ \
+ "?FormID=geneWiki&action=update&Id=%d&symbol=%s" %(item[-1], self.symbol),
+ onClick = "return confirm('Any user can edit any GeneWiki entry, with changes showing up immediately. The history of previous versions of this entry are stored and available for reference. Click OK to continue.');" ,
+ text=HT.Image("/images/modify.gif", border=0), title="Modify Entry", Class="fwn")
+ , width=20, valign="top"
+ ),
+ HT.TD(
+ HT.Href(url=os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE)+ \
+ "?FormID=geneWiki&action=history&Id=%d&symbol=%s" %(item[-1], self.symbol),
+ text=HT.Image("/images/history.gif", border=0), title="History of Entry", Class="fwn")
+ , width=20, valign="top"
+ )
+ )
+ if self.privilege_to_delete_entry:
+ myTR.append(HT.TD(
+ HT.Href(url=os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE)+ \
+ "?FormID=geneWiki&action=del&Id=%d&symbol=%s" %(item[-1], self.symbol),
+ onClick = "return confirm('Do you really want to delete this entry, click YES to continue.');" ,
+ text=HT.Image("/images/trash.gif", border=0), title="Delete Entry", Class="fwn")
+ , width=20, valign="top"
+ ))
+ geneRIFBody.append(myTR)
+ else:
+ geneRIFBody.append(HT.TR(
+ HT.TD(" ", width=20),
+ HT.TD(HT.U("There is no GeneWiki entry for this gene."), colspan=5+self.additional_colspan),
+ ))
+
+ self.cursor.execute("select distinct Species.FullName, GeneRIF_BASIC.GeneId, GeneRIF_BASIC.comment, GeneRIF_BASIC.PubMed_ID from GeneRIF_BASIC, Species where GeneRIF_BASIC.symbol='%s' and GeneRIF_BASIC.SpeciesId = Species.Id order by Species.Id, GeneRIF_BASIC.createtime" % self.symbol)
+ results = self.cursor.fetchall()
+ if results:
+ geneRIFBody.append(HT.TR(HT.TD(), HT.TD("GeneRIF from NCBI:", colspan=4+self.additional_colspan, Class="fwb")))
+ for i, item in enumerate(results):
+ PubMedLink = HT.Href(text="PubMed", target = "_blank",
+ url = webqtlConfig.PUBMEDLINK_URL % item[3], Class="fwn")
+ GeneLink = HT.Href(text= item[0], target='_blank',\
+ url=webqtlConfig.NCBI_LOCUSID % item[1], Class="fwn")
+ myTR = HT.TR(
+ HT.TD(" ", width=20),
+ HT.TD(HT.Strong(i+1, ". "), valign="top"),
+ HT.TD(HT.Paragraph(item[2], " (", GeneLink,") ", PubMedLink), valign="top", colspan=3+self.additional_colspan))
+ geneRIFBody.append(myTR)
+
+ TD_LR = HT.TD(valign="top", bgcolor="#eeeeee")
+ help1 = HT.Href(url="/GeneWikihelp.html", text=" help document", Class="fwn", target="_blank")
+ title = HT.Paragraph("GeneWiki Entries", Class="title")
+ intro = HT.Blockquote("GeneWiki enables you to enrich the annotation of genes and transcripts. Please submit or edit a GeneWiki note (500 characters max) related to a gene, its transcripts, or proteins. When possible include PubMed identifiers or web resource links (URL addresses). Please ensure that the additions will have widespread use. For additional information, check the GeneWiki ", help1, ".")
+
+ TD_LR.append(title, intro, HT.Blockquote(geneRIFBody))
+ self.dict['title'] = "GeneWiki for %s" % self.symbol
+ self.dict['body'] = TD_LR
+
+
+ def delRIF(self):
+ if self.privilege_to_delete_entry:
+ self.cursor.execute("update GeneRIF set display= 0 where Id = %d" % self.Id)
+
+ def insertResultPage(self, fd):
+ try:
+ password = fd.formdata.getvalue("password", "")
+ filename = fd.formdata.getvalue("filename")
+ code = glob.glob(os.path.join(webqtlConfig.IMGDIR,filename+"_.*"))
+ code = string.split(code[0], '.')[-1]
+ if string.lower(code) != string.lower(password):
+ return 0
+ TD_LR = HT.TD(valign="top", bgcolor="#eeeeee")
+ title = HT.Paragraph("Add GeneWiki Entry", Class="title")
+ self.cursor.execute("Select max(Id) from GeneRIF")
+ if self.action == 'update':
+ #old record
+ maxId = int(self.Id)
+ self.cursor.execute("select max(versionId)+1 from GeneRIF where Id=%s" % maxId)
+ newversionId = self.cursor.fetchone()[0]
+ self.cursor.execute("update GeneRIF set versionId = %d where Id=%d and versionId = 0" % (newversionId, maxId))
+ self.cursor.execute("update GeneRIFXRef set versionId = %d where GeneRIFId=%d and versionId = 0" % (newversionId, maxId))
+ else:
+ #new record
+ try:
+ maxId = self.cursor.fetchone()[0] +1
+ except:
+ maxId = 1
+
+ for item in self.fields:
+ if not getattr(self, item):
+ setattr(self, item, None)
+ self.cursor.execute("""insert into GeneRIF (id, symbol, PubMed_ID, SpeciesId, comment, email, createtime, user_ip, display, weburl, initial, reason)
+ values (%s, %s, %s, %s, %s, %s, Now(), %s, 1, %s, %s, %s)""",
+ (maxId, self.symbol, self.pubmedid, string.split(self.species, ":")[-1], self.comment,
+ self.email, fd.remote_ip, self.weburl, self.initial, self.reason))
+ if self.genecategory:
+ Ids = string.split(self.genecategory)
+ for item in Ids:
+ self.cursor.execute("insert into GeneRIFXRef(GeneRIFId, GeneCategoryId) values(%s, %s)" % (maxId, item))
+ return 2
+ except:
+ heading = self.dict['title']
+ detail = ["Error occurred while adding your Gene RIFs."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return 1
+
+
diff --git a/web/webqtl/geneWiki/__init__.py b/web/webqtl/geneWiki/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/genomeGraph/__init__.py b/web/webqtl/genomeGraph/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/genomeGraph/cmdGenomeScanPage.py b/web/webqtl/genomeGraph/cmdGenomeScanPage.py
new file mode 100755
index 00000000..d880ce69
--- /dev/null
+++ b/web/webqtl/genomeGraph/cmdGenomeScanPage.py
@@ -0,0 +1,532 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import string
+import piddle as pid
+import os
+import math
+
+from htmlgen import HTMLgen2 as HT
+
+from utility import svg
+from base import webqtlConfig
+from utility import Plot
+from utility import webqtlUtil
+from base.webqtlDataset import webqtlDataset
+from base.templatePage import templatePage
+
+
+#########################################
+# Genome Scan PAGE
+#########################################
+class cmdGenomeScanPage(templatePage):
+ def __init__(self,fd):
+ templatePage.__init__(self,fd)
+ if not self.openMysql():
+ return
+ self.database = fd.formdata.getvalue('database', '')
+ db = webqtlDataset(self.database, self.cursor)
+
+ try:
+ self.openURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + \
+ '?FormID=showDatabase&database=%s&incparentsf1=1&ProbeSetID=' % self.database
+
+ if db.type != "ProbeSet" or not db.id:
+ raise DbNameError
+
+ self.cursor.execute("""
+ Select
+ InbredSet.Name
+ From
+ ProbeSetFreeze, ProbeFreeze, InbredSet
+ whERE
+ ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND
+ ProbeFreeze.InbredSetId = InbredSet.Id AND
+ ProbeSetFreeze.Id = %d
+ """ % db.id)
+ thisRISet = self.cursor.fetchone()[0]
+ if thisRISet =='BXD300':
+ thisRISet = 'BXD'
+
+ ##################################################
+ # exon data is too huge for GenoGraph, skip it #
+ ##################################################
+ self.cursor.execute('select count(*) from ProbeSetXRef where ProbeSetFreezeId=%d' % db.id)
+ amount = self.cursor.fetchall()
+ if amount:
+ amount = amount[0][0]
+ if amount>100000:
+ heading = "Whole Transcriptome Mapping"
+ detail = ["Whole Transcriptome Mapping is not available for this data set."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.cursor.execute("""
+ Select
+ ProbeSet.Id, ProbeSet.Name, ProbeSet.Chr, ProbeSet.Mb, ProbeSetXRef.Locus, ProbeSetXRef.pValue
+ From
+ ProbeSet, ProbeSetXRef
+ whERE
+ ProbeSetXRef.ProbeSetFreezeId = %d AND
+ ProbeSetXRef.ProbeSetId = ProbeSet.Id AND
+ ProbeSetXRef.Locus is not NULL
+ """ % db.id)
+ results = self.cursor.fetchall()
+
+ if results:
+ self.mouseChrLengthDict, sum = self.readMouseGenome(thisRISet)
+
+ import reaper
+ markerGMb = {}
+ genotype_1 = reaper.Dataset()
+ genotype_1.read(os.path.join(webqtlConfig.GENODIR, thisRISet + '.geno'))
+ for chr in genotype_1:
+ chrlen = self.mouseChrLengthDict[chr.name]
+
+ for locus in chr:
+ markerGMb[locus.name] = locus.Mb + chrlen
+
+ try:
+ FDR = float(fd.formdata.getvalue("fdr", ""))
+ except:
+ FDR = 0.2
+ self.grid = fd.formdata.getvalue("grid", "")
+
+ NNN = len(results)
+ results = list(results)
+ results.sort(self.cmppValue)
+
+ MbCoord = []
+ MbCoord2 = []
+
+ for j in range(NNN, 0, -1):
+ if results[j-1][-1] <= (FDR*j)/NNN:
+ break
+
+ if j > 0:
+ for i in range(j-1, -1, -1):
+ _Id, _probeset, _chr, _Mb, _marker, _pvalue = results[i]
+ try:
+ MbCoord.append([markerGMb[_marker], _Mb+self.mouseChrLengthDict[string.strip(_chr)], _probeset, _chr, _Mb, _marker, _pvalue])
+ except:
+ pass
+
+ filename=webqtlUtil.genRandStr("gScan_")
+ canvas = pid.PILCanvas(size=(1280,880))
+ self.drawGraph(canvas, MbCoord, cLength=sum)
+
+ canvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png')
+
+ canvasSVG = self.drawSVG(MbCoord, cLength=sum, size=(1280,880))
+ canvasSVG.toXml(os.path.join(webqtlConfig.IMGDIR, filename+'.svg')) #and write it to file
+
+ img = HT.Embed(src='/image/'+filename+'.png', width=1280, height=880, border=0, alt='Genome Scan')
+ img2 = HT.Embed(src='/image/'+filename+'.svg', width=1280, height=880, border=0)
+ TD_LR = HT.TD(colspan=2,height=200,width="100%",bgColor='#eeeeee')
+
+ heading = HT.Paragraph('Whole Transcriptome Mapping')
+ heading.__setattr__("class","title")
+ intro = HT.Blockquote()
+ intro.append('The plot below is the Whole Transcriptome Mapping of Database ')
+ intro.append(HT.Href(text=db.fullname, url = webqtlConfig.INFOPAGEHREF % db.name ,target='_blank',Class="normalsize"))
+ intro.append(". %d from a total of %d ProbeSets were utilized to generate this graph." % (len(MbCoord), len(results)))
+
+ mainfm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', \
+ name=webqtlUtil.genRandStr("fm_"), submit=HT.Input(type='hidden'))
+ mainfm.append(HT.Input(name='database', value=self.database, type='hidden'))
+ mainfm.append(HT.Input(name='FormID', value='transciptMapping', type='hidden'))
+
+ mainfm.append("
+ ''' % (datasetId,datasetId)
+
+ body=contentTitle+content
+ # Note: 'templateParameters' includes parameters required for template.py
+ # templateParameters = ['title','basehref','js1','js2','layer','header','body', 'footer']
+ templateParameters =[title,'','','','',headerInfo,body,footerInfo]
+
+ # build template file
+ templateFile=template.template % tuple(templateParameters)
+ InfoFileHandler = open(InfoFileURL, 'w')
+ # write template file into Info .html file
+ InfoFileHandler.write(templateFile)
+ InfoFileHandler.close()
+
+
+# select all ProbeSet names from datatable 'ProbeSetFreeze'
+cursor.execute("select Id, Name, FullName from ProbeSetFreeze ")
+results = cursor.fetchall()
+for item in results:
+ datasetId = item[0]
+ datasetName =item[1]
+ datasetFullName =item[2]
+ InfoFileURL = InfoFilePath+datasetName+".html"
+ # check Info html file exist or not
+ if not os.path.exists(InfoFileURL):
+ createTemplateForInfoFile(datasetId=datasetId,datasetFullName=datasetFullName,InfoFileURL=InfoFileURL)
+
+
+
+
+
+
+
+
+
+
diff --git a/web/webqtl/maintainance/genSelectDatasetJS.py b/web/webqtl/maintainance/genSelectDatasetJS.py
new file mode 100755
index 00000000..bc88beec
--- /dev/null
+++ b/web/webqtl/maintainance/genSelectDatasetJS.py
@@ -0,0 +1,637 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by NL 2011/01/27
+
+# created by Ning Liu 07/01/2010
+# This script is to generate selectDatasetMenu.js file for cascade menu in the main search page http://www.genenetwork.org/.
+# This script will be run automatically every one hour or manually when database has been changed .
+import sys, os
+
+current_file_name = __file__
+pathname = os.path.dirname( current_file_name )
+abs_path = os.path.abspath(pathname)
+sys.path.insert(0, abs_path + '/..')
+
+import MySQLdb
+import os
+import string
+import time
+import datetime
+
+from base import template
+from base import webqtlConfig
+
+#################################################################################
+# input: searchArray, targetValue
+# function: retrieve index info of target value in designated array (searchArray)
+# output: return index info
+##################################################################################
+def getIndex(searchArray=None, targetValue=None):
+ for index in range(len(searchArray)):
+ if searchArray[index][0]==targetValue:
+ return index
+
+# build MySql database connection
+con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD)
+cursor = con.cursor()
+
+# create js_select.js file
+fileHandler = open(webqtlConfig.HTMLPATH + 'javascript/selectDatasetMenu.js', 'w')
+
+# define SpeciesString, GroupString, TypeString, DatabasingString, LinkageString for output
+# outputSpeciesStr is for building Species Array(sArr) in js file; outputGroupStr is for Group Array(gArr)
+# outputTypeStr is for Type Array(tArr); outputDatabaseStr is for Database Array(dArr)
+# outputLinkStr is for Linkage Array(lArr)
+outputTimeStr ="/* Generated Date : %s , Time : %s */ \n" % (datetime.date.today(),time.strftime("%H:%M ", time.localtime()))
+outputTimeStr =""
+outputSpeciesStr ='var sArr = [\n{txt:\'\',val:\'\'},\n'
+outputGroupStr ='var gArr = [\n{txt:\'\',val:\'\'},\n'
+outputTypeStr ='var tArr = [\n{txt:\'\',val:\'\'},\n'
+outputDatabaseStr ='var dArr = [\n{txt:\'\',val:\'\'},\n'
+outputLinkStr ='var lArr = [\n null,\n'
+
+# built speices array in js file for select menu in the main search page http://www.genenetwork.org/
+cursor.execute("select Name, MenuName from Species order by OrderId")
+speciesResult = cursor.fetchall()
+speciesTotalResult = list(speciesResult)
+speciesResultsTotalNum = cursor.rowcount
+if speciesResultsTotalNum >0:
+ for speciesItem in speciesResult:
+ speciesVal = speciesItem[0]
+ speciesTxt = speciesItem[1]
+ outputSpeciesStr += '{txt:\'%s\',val:\'%s\'},\n'%(speciesTxt,speciesVal)
+# 'All Species' option for 'Species' select menu
+outputSpeciesStr +='{txt:\'All Species\',val:\'All Species\'}];\n\n'
+#speciesTotalResult is a list which inclues all species' options
+speciesTotalResult.append(('All Species','All Species'))
+
+# built group array in js file for select menu in the main search page http://www.genenetwork.org/
+cursor.execute("select distinct InbredSet.Name, InbredSet.FullName from InbredSet, Species, ProbeFreeze, GenoFreeze, PublishFreeze where InbredSet.SpeciesId= Species.Id and InbredSet.Name != 'BXD300' and (PublishFreeze.InbredSetId = InbredSet.Id or GenoFreeze.InbredSetId = InbredSet.Id or ProbeFreeze.InbredSetId = InbredSet.Id) order by InbredSet.Name")
+groupResults = cursor.fetchall()
+groupTotalResults = list(groupResults)
+groupResultsTotalNum = cursor.rowcount
+if groupResultsTotalNum > 0:
+ for groupItem in groupResults:
+ groupVal = groupItem[0]
+ groupTxt = groupItem[1]
+ outputGroupStr += '{txt:\'%s\',val:\'%s\'},\n'%(groupTxt,groupVal)
+# add 'All Groups' option for 'Group' select menu
+outputGroupStr +='{txt:\'All Groups\',val:\'all groups\'}];\n\n'
+# groupTotalResults is a list which inclues all groups' options
+groupTotalResults.append(('all groups','All Groups'))
+
+# built type array in js file for select menu in the main search page http://www.genenetwork.org/
+cross = groupVal
+cursor.execute("select distinct Tissue.Name, concat(Tissue.Name, ' mRNA') from ProbeFreeze, ProbeSetFreeze, InbredSet, Tissue where ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.public > %d order by Tissue.Name" % (webqtlConfig.PUBLICTHRESH))
+typeResults = cursor.fetchall()
+typeTotalResults = list(typeResults)
+typeResultsTotalNum = cursor.rowcount
+if typeResultsTotalNum > 0:
+ for typeItem in typeResults:
+ typeVal = typeItem[0]
+ typeTxt = typeItem[1]
+ outputTypeStr += '{txt:\'%s\',val:\'%s\'},\n'%(typeTxt,typeVal)
+# add 'Phenotypes' and 'Genotypes' options for 'Type' select menu
+outputTypeStr +='{txt:\'Phenotypes\',val:\'Phenotypes\'},\n'
+outputTypeStr +='{txt:\'Genotypes\',val:\'Genotypes\'}];\n\n'
+# typeTotalResults is a list which inclues all types' options
+typeTotalResults.append(('Phenotypes','Phenotypes'))
+typeTotalResults.append(('Genotypes','Genotypes'))
+
+# built dataset array in js file for select menu in the main search page http://www.genenetwork.org/
+tissue = typeVal
+cursor.execute("select ProbeSetFreeze.Name, ProbeSetFreeze.FullName from ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue where ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and ProbeSetFreeze.public > %d order by ProbeSetFreeze.CreateTime desc" % (webqtlConfig.PUBLICTHRESH))
+datasetResults = cursor.fetchall()
+datasetTotalResults = list(datasetResults)
+datasetResultsTotalNum = cursor.rowcount
+if datasetResultsTotalNum > 0:
+ for datasetItem in datasetResults:
+ datasetVal = datasetItem[0]
+ datasetTxt = datasetItem[1]
+ outputDatabaseStr += '{txt:\'%s\',val:\'%s\'},\n'%(datasetTxt,datasetVal)
+
+# This part is to built linkage array in js file, the linkage is among Species, Group, Type and Database.
+# The format of linkage array is [speciesIndex, groupIndex, typeIndex, databaseIndex]
+if speciesResultsTotalNum >0:
+ for speciesItem in speciesResult:
+ speciesVal = speciesItem[0]
+ sIndex = getIndex(searchArray=speciesTotalResult,targetValue=speciesVal)+1
+
+ # retrieve group info based on specie
+ cursor.execute("select distinct InbredSet.Name, InbredSet.FullName from InbredSet, Species, ProbeFreeze, GenoFreeze, PublishFreeze where InbredSet.SpeciesId= Species.Id and Species.Name='%s' and InbredSet.Name != 'BXD300' and (PublishFreeze.InbredSetId = InbredSet.Id or GenoFreeze.InbredSetId = InbredSet.Id or ProbeFreeze.InbredSetId = InbredSet.Id) order by InbredSet.Name" % speciesVal)
+ groupResults = cursor.fetchall()
+ groupResultsNum = cursor.rowcount
+
+ if groupResultsNum > 0:
+ for groupItem in groupResults:
+ groupVal = groupItem[0]
+ gIndex = getIndex(searchArray=groupTotalResults, targetValue=groupVal)+1
+
+ cross = groupVal
+ # if group also exists in PublishFreeze table, then needs to add related Published Phenotypes in Database Array(dArr) and Linkage Array(lArr)
+ # 'MDP' case is related to 'Mouse Phenome Database'
+ cursor.execute("select PublishFreeze.Id from PublishFreeze, InbredSet where PublishFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = '%s'" % cross)
+ if (cursor.fetchall()):
+ typeVal = "Phenotypes"
+ if cross=='MDP':
+ datasetTxt = "Mouse Phenome Database"
+ else:
+ datasetTxt = "%s Published Phenotypes" % cross
+ datasetVal = "%sPublish" % cross
+ outputDatabaseStr += '{txt:\'%s\',val:\'%s\'},\n'% (datasetTxt,datasetVal)
+ datasetTotalResults.append(('%s'% datasetVal,'%s' % datasetTxt))
+
+ tIndex = getIndex(searchArray=typeTotalResults,targetValue=typeVal)+1
+ dIndex = getIndex(searchArray=datasetTotalResults, targetValue=datasetVal)+1
+ outputLinkStr +='[%d,%d,%d,%d],\n'%(sIndex,gIndex,tIndex,dIndex)
+
+ # if group also exists in GenoFreeze table, then needs to add related Genotypes in database Array(dArr)
+ cursor.execute("select GenoFreeze.Id from GenoFreeze, InbredSet where GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = '%s'" % cross)
+ if (cursor.fetchall()):
+ typeVal = "Genotypes"
+ datasetTxt = "%s Genotypes" % cross
+ datasetVal = "%sGeno" % cross
+ outputDatabaseStr += '{txt:\'%s\',val:\'%s\'},\n'%(datasetTxt,datasetVal)
+ typeTotalResults.append(('Genotypes','Genotypes'))
+ datasetTotalResults.append(('%s'% datasetVal,'%s' % datasetTxt))
+
+ tIndex = getIndex(searchArray=typeTotalResults,targetValue=typeVal)+1
+ dIndex = getIndex(searchArray=datasetTotalResults, targetValue=datasetVal)+1
+ outputLinkStr +='[%d,%d,%d,%d],\n'%(sIndex,gIndex,tIndex,dIndex)
+
+ # retrieve type(tissue) info based on group
+ # if cross is equal to 'BXD', then need to seach for 'BXD' and 'BXD300' InbredSet
+ if cross == "BXD":
+ cross2 = "BXD', 'BXD300"
+ else:
+ cross2 = cross
+ cursor.execute("select distinct Tissue.Name, concat(Tissue.Name, ' mRNA') from ProbeFreeze, ProbeSetFreeze, InbredSet, Tissue where ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name in ('%s') and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.public > %d order by Tissue.Name" % (cross2, webqtlConfig.PUBLICTHRESH))
+ typeResults = cursor.fetchall()
+ typeResultsNum = cursor.rowcount
+
+ if typeResultsNum > 0:
+ for typeItem in typeResults:
+ typeVal = typeItem[0]
+ tIndex = getIndex(searchArray=typeTotalResults, targetValue=typeVal)+1
+ # retrieve database(dataset) info based on group(InbredSet) and type(Tissue)
+ tissue = typeVal
+ cursor.execute("select ProbeSetFreeze.Name, ProbeSetFreeze.FullName from ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue where ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name in ('%s') and Tissue.name = '%s' and ProbeSetFreeze.public > %d order by ProbeSetFreeze.CreateTime desc" % (cross2, tissue, webqtlConfig.PUBLICTHRESH))
+ datasetResults = cursor.fetchall()
+ datasetResultsNum = cursor.rowcount
+
+ if datasetResultsNum > 0:
+ for datasetItem in datasetResults:
+ datasetVal = datasetItem[0]
+ dIndex = getIndex(searchArray=datasetTotalResults, targetValue=datasetVal)+1
+ outputLinkStr +='[%d,%d,%d,%d],\n'%(sIndex,gIndex,tIndex,dIndex)
+
+# add 'All Phenotypes' option for 'Database' select menu
+# for 'All Species'option in 'Species' select menu, 'Database' select menu will show 'All Phenotypes' option
+outputDatabaseStr += '{txt:\'%s\',val:\'%s\'}];\n\n'%('All Phenotypes','_allPublish')
+datasetTotalResults.append(('_allPublish','All Phenotypes'))
+
+sIndex = getIndex(searchArray=speciesTotalResult,targetValue='All Species')+1
+gIndex = getIndex(searchArray=groupTotalResults, targetValue='all groups')+1
+tIndex = getIndex(searchArray=typeTotalResults,targetValue='Phenotypes')+1
+dIndex = getIndex(searchArray=datasetTotalResults, targetValue='_allPublish')+1
+outputLinkStr +='[%d,%d,%d,%d]];\n\n'%(sIndex,gIndex,tIndex,dIndex)
+
+# Combine sArr, gArr, tArr, dArr and lArr output string together
+outputStr = outputTimeStr+outputSpeciesStr+outputGroupStr+outputTypeStr+outputDatabaseStr+outputLinkStr
+outputStr +='''
+
+/*
+* function: based on different browser use, will have different initial actions;
+* Once the index.html page is loaded, this function will be called
+*/
+function initialDatasetSelection()
+{
+ defaultSpecies =getDefaultValue('species');
+ defaultSet =getDefaultValue('cross');
+ defaultType =getDefaultValue('tissue');
+ defaultDB =getDefaultValue('database');
+
+ if (navigator.userAgent.indexOf('MSIE')>=0)
+ {
+ sOptions = fillOptionsForIE(null,defaultSpecies);
+ var menu0 ="";
+ document.getElementById('menu0').innerHTML = menu0;
+
+ gOptions = fillOptionsForIE('species',defaultSet);
+ var menu1 ="";
+ document.getElementById('menu1').innerHTML =menu1;
+
+ tOptions = fillOptionsForIE('cross',defaultType);
+ var menu2 ="";
+ document.getElementById('menu2').innerHTML =menu2;
+
+ dOptions = fillOptionsForIE('tissue',defaultDB);
+ var menu3 ="";
+ document.getElementById('menu3').innerHTML =menu3;
+
+ }else{
+ fillOptions(null);
+ }
+ searchtip();
+}
+
+/*
+* input: selectObjId (designated select menu, such as species, cross, etc... )
+* defaultValue (default Value of species, cross,tissue or database)
+* function: special for IE browser,setting options value for select menu dynamically based on linkage array(lArr),
+* output: options string
+*/
+function fillOptionsForIE(selectObjId,defaultValue)
+{
+ var options='';
+ if(selectObjId==null)
+ {
+ var len = sArr.length;
+ for (var i=1; i < len; i++) {
+ // setting Species' option
+ if( sArr[i].val==defaultValue){
+ options =options+"";
+ }else{
+ options =options+"";
+ }
+ }
+ }else if(selectObjId=='species')
+ {
+ var speciesObj = document.getElementById('species');
+ var len = lArr.length;
+ var arr = [];
+ var idx = 0;
+ for (var i=1; i < len; i++) {
+ //get group(cross) info from lArr
+ if(lArr[i][0]==(getIndexByValue('species',speciesObj.value)).toString()&&!Contains(arr,lArr[i][1]))
+ {
+ arr[idx++]=lArr[i][1];
+ }
+ }
+ idx=0;
+ len = arr.length;
+ removeOptions("cross");
+ for (var i=0; i < len; i++) {
+ // setting Group's option
+ if( gArr[arr[i]].val==defaultValue){
+ options =options+"";
+ }else{
+ options =options+"";
+ }
+
+ }
+ }else if(selectObjId=='cross')
+ {
+ var speciesObj = document.getElementById('species');
+ var groupObj = document.getElementById('cross');
+ var len = lArr.length;
+ var arr = [];
+ var idx = 0;
+ for (var i=1; i < len; i++) {
+ //get type(tissue) info from lArr
+ if(lArr[i][0]==(getIndexByValue('species',speciesObj.value)).toString()&&lArr[i][1]==(getIndexByValue('cross',groupObj.value)).toString()&&!Contains(arr,lArr[i][2]))
+ {
+ arr[idx++]=lArr[i][2];
+ }
+ }
+ idx=0;
+ len = arr.length;
+ removeOptions("tissue");
+ for (var i=0; i < len; i++) {
+ // setting Type's option
+ if( tArr[arr[i]].val==defaultValue){
+ options =options+"";
+ }else{
+ options =options+"";
+ }
+ }
+
+ }else if(selectObjId=='tissue')
+ {
+ var speciesObj = document.getElementById('species');
+ var groupObj = document.getElementById('cross');
+ var typeObj = document.getElementById('tissue');
+
+ var len = lArr.length;
+ var arr = [];
+ var idx = 0;
+ for (var i=1; i < len; i++) {
+ //get dataset(database) info from lArr
+ if(lArr[i][0]==(getIndexByValue('species',speciesObj.value)).toString()&&lArr[i][1]==(getIndexByValue('cross',groupObj.value)).toString()&&lArr[i][2]==(getIndexByValue('tissue',typeObj.value)).toString()&&!Contains(arr,lArr[i][3]))
+ {
+ arr[idx++]=lArr[i][3];
+ }
+ }
+ idx=0;
+ len = arr.length;
+ removeOptions("database");
+ for (var i=0; i < len; i++) {
+ // setting Database's option
+ if( dArr[arr[i]].val==defaultValue){
+ options =options+"";
+ }else{
+ options =options+"";
+ }
+ }
+ }
+ return options;
+}
+/*
+* input: selectObjId (designated select menu, such as species, cross, etc... )
+* function: setting options value for select menu dynamically based on linkage array(lArr)
+* output: null
+*/
+function fillOptions(selectObjId)
+{
+ if(selectObjId==null)
+ {
+
+ var speciesObj = document.getElementById('species');
+ var len = sArr.length;
+ for (var i=1; i < len; i++) {
+ // setting Species' option
+ speciesObj.options[i-1] = new Option(sArr[i].txt, sArr[i].val);
+ }
+ updateChocie('species');
+
+ }else if(selectObjId=='species')
+ {
+ var speciesObj = document.getElementById('species');
+ var groupObj = document.getElementById('cross');
+ var len = lArr.length;
+ var arr = [];
+ var idx = 0;
+ for (var i=1; i < len; i++) {
+ //get group(cross) info from lArr
+ if(lArr[i][0]==(getIndexByValue('species',speciesObj.value)).toString()&&!Contains(arr,lArr[i][1]))
+ {
+ arr[idx++]=lArr[i][1];
+ }
+ }
+ idx=0;
+ len = arr.length;
+ removeOptions("cross");
+ for (var i=0; i < len; i++) {
+ // setting Group's option
+ groupObj.options[idx++] = new Option(gArr[arr[i]].txt, gArr[arr[i]].val);
+ }
+ updateChocie('cross');
+
+ }else if(selectObjId=='cross')
+ {
+ var speciesObj = document.getElementById('species');
+ var groupObj = document.getElementById('cross');
+ var typeObj = document.getElementById('tissue');
+ var len = lArr.length;
+ var arr = [];
+ var idx = 0;
+ for (var i=1; i < len; i++) {
+ //get type(tissue) info from lArr
+ if(lArr[i][0]==(getIndexByValue('species',speciesObj.value)).toString()&&lArr[i][1]==(getIndexByValue('cross',groupObj.value)).toString()&&!Contains(arr,lArr[i][2]))
+ {
+ arr[idx++]=lArr[i][2];
+ }
+ }
+ idx=0;
+ len = arr.length;
+ removeOptions("tissue");
+ for (var i=0; i < len; i++) {
+ // setting Type's option
+ typeObj.options[idx++] = new Option(tArr[arr[i]].txt, tArr[arr[i]].val);
+ }
+ updateChocie('tissue');
+
+ }else if(selectObjId=='tissue')
+ {
+ var speciesObj = document.getElementById('species');
+ var groupObj = document.getElementById('cross');
+ var typeObj = document.getElementById('tissue');
+ var databaseObj = document.getElementById('database');
+
+ var len = lArr.length;
+ var arr = [];
+ var idx = 0;
+ for (var i=1; i < len; i++) {
+ //get dataset(database) info from lArr
+ if(lArr[i][0]==(getIndexByValue('species',speciesObj.value)).toString()&&lArr[i][1]==(getIndexByValue('cross',groupObj.value)).toString()&&lArr[i][2]==(getIndexByValue('tissue',typeObj.value)).toString()&&!Contains(arr,lArr[i][3]))
+ {
+ arr[idx++]=lArr[i][3];
+ }
+ }
+ idx=0;
+ len = arr.length;
+ removeOptions("database");
+ for (var i=0; i < len; i++) {
+ // setting Database's option
+ databaseObj.options[idx++] = new Option(dArr[arr[i]].txt, dArr[arr[i]].val);
+ }
+ updateChocie('database');
+ }
+}
+
+/*
+* input: arr (targeted array); obj (targeted value)
+* function: check whether targeted array contains targeted value or not
+* output: return true, if array contains targeted value, otherwise return false
+*/
+function Contains(arr,obj) {
+ var i = arr.length;
+ while (i--) {
+ if (arr[i] == obj) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+* input: selectObj (designated select menu, such as species, cross, etc... )
+* function: clear designated select menu's option
+* output: null
+*/
+function removeOptions(selectObj) {
+ if (typeof selectObj != 'object'){
+ selectObj = document.getElementById(selectObj);
+ }
+ var len = selectObj.options.length;
+ for (var i=0; i < len; i++) {
+ // clear current selection
+ selectObj.options[0] = null;
+ }
+}
+
+/*
+* input: selectObjId (designated select menu, such as species, cross, etc... )
+* Value: target value
+* function: retrieve Index info of target value in designated array
+* output: index info
+*/
+function getIndexByValue(selectObjId,val)
+{
+ if(selectObjId=='species')
+ {
+ for(var i=1;i=0){
+ //setting option's selected status
+ Obj.options[idx].selected=true;
+ //update the following select menu
+ fillOptions(objId);
+ }else{
+ Obj.options[0].selected=true;
+ fillOptions(objId);
+ }
+}
+
+// setting option's selected status based on default setting or cookie setting for Species, Group, Type and Database select menu in the main search page http://www.genenetwork.org/
+function updateChocie(selectObjId){
+
+ if (selectObjId =='species')
+ {
+ defaultSpecies= getDefaultValue('species');
+ //setting option's selected status
+ setChoice('species',defaultSpecies);
+ }else if (selectObjId =='cross')
+ {
+ defaultSet= getDefaultValue('cross');
+ //setting option's selected status
+ setChoice('cross',defaultSet);
+ }else if (selectObjId =='tissue')
+ {
+ defaultType= getDefaultValue('tissue');
+ //setting option's selected status
+ setChoice('tissue',defaultType);
+ }else if (selectObjId =='database')
+ {
+ defaultDB= getDefaultValue('database');
+ //setting option's selected status
+ setChoice('database',defaultDB);
+ }
+}
+
+//get default value;if cookie exists, then use cookie value, otherwise use default value
+function getDefaultValue(selectObjId){
+ //define default value
+ var defaultSpecies = 'mouse'
+ var defaultSet = 'BXD'
+ var defaultType = 'Hippocampus'
+ var defaultDB = 'HC_M2_0606_P'
+
+ if (selectObjId =='species')
+ {
+ //if cookie exists, then use cookie value, otherwise use default value
+ var cookieSpecies = getCookie('defaultSpecies');
+ if(cookieSpecies)
+ {
+ defaultSpecies= cookieSpecies;
+ }
+ return defaultSpecies;
+ }else if (selectObjId =='cross'){
+ var cookieSet = getCookie('defaultSet');
+ if(cookieSet){
+ defaultSet= cookieSet;
+ }
+ return defaultSet;
+ }else if (selectObjId =='tissue'){
+ var cookieType = getCookie('defaultType');
+ if(cookieType){
+ defaultType= cookieType;
+ }
+ return defaultType;
+ }else if (selectObjId =='database')
+ {
+ var cookieDB = getCookie('defaultDB');
+ if(cookieDB){
+ defaultDB= cookieDB;
+ }
+ return defaultDB;
+ }
+
+}
+
+//setting default value into cookies for the dropdown menus: Species,Group, Type, and Database
+function setDefault(thisform){
+
+ setCookie('cookieTest', 'cookieTest', 1);
+ var cookieTest = getCookie('cookieTest');
+ delCookie('cookieTest');
+ if (cookieTest){
+ var defaultSpecies = thisform.species.value;
+ setCookie('defaultSpecies', defaultSpecies, 10);
+ var defaultSet = thisform.cross.value;
+ setCookie('defaultSet', defaultSet, 10);
+ var defaultType = thisform.tissue.value;
+ setCookie('defaultType', defaultType, 10);
+ var defaultDB = thisform.database.value;
+ setCookie('defaultDB', defaultDB, 10);
+ updateChocie('species');
+ updateChocie('cross');
+ updateChocie('tissue');
+ updateChocie('database');
+ alert("The current settings are now your default");
+ }
+ else{
+ alert("You need to enable Cookies in your browser.");
+ }
+}
+
+'''
+# write all strings' info into selectDatasetMenu.js file
+fileHandler.write(outputStr)
+fileHandler.close()
diff --git a/web/webqtl/maintainance/updateMenuJS.py b/web/webqtl/maintainance/updateMenuJS.py
new file mode 100755
index 00000000..8b6e25d3
--- /dev/null
+++ b/web/webqtl/maintainance/updateMenuJS.py
@@ -0,0 +1,127 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# created by Lei Yan 02/08/2011
+import sys, os
+import MySQLdb
+import string
+
+
+
+abs_path = os.path.abspath(os.path.dirname(__file__))
+path1 = abs_path + "/.."
+path2 = abs_path + "/../../javascript"
+sys.path.insert(0, path1)
+
+#must import GN python files after add path
+from base import webqtlConfig
+
+# build MySql database connection
+con = MySQLdb.Connect(db=webqtlConfig.DB_NAME, host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER, passwd=webqtlConfig.DB_PASSWD)
+cursor = con.cursor()
+cursor.execute("SELECT id,menuname FROM Species ORDER BY OrderId")
+results = list(cursor.fetchall())
+collectionsText = ""
+for result in results:
+ specieid = result[0]
+ speciename = result[1]
+ collectionsText += ("['" + speciename + "', ")
+ collectionsText += ("null, ")
+ collectionsText += ("null, ")
+ collectionsText += "\n"
+ cursor.execute("select name from InbredSet where speciesid=" + str(specieid))
+ results2 = list(cursor.fetchall())
+ for result2 in results2:
+ inbredsetName = result2[0]
+ if not cmp(inbredsetName, "BXD300"):
+ continue
+ collectionsText += "\t"
+ collectionsText += ("['" + inbredsetName + "', ")
+ collectionsText += ("'/webqtl/main.py?FormID=dispSelection&RISet=" + inbredsetName + "'], ")
+ collectionsText += "\n"
+ collectionsText += "],"
+ collectionsText += "\n"
+collectionsText = collectionsText.strip()
+
+jstext = """/*
+ --- menu items ---
+ note that this structure has changed its format since previous version.
+ additional third parameter is added for item scope settings.
+ Now this structure is compatible with Tigra Menu GOLD.
+ Format description can be found in product documentation.
+*/
+var MENU_ITEMS = [
+ ['menu_grp1', null, null,
+ ['GeneNetwork Intro', '/home.html'],
+ ['Enter Trait Data', '/webqtl/main.py?FormID=submitSingleTrait'],
+ ['Batch Submission', '/webqtl/main.py?FormID=batSubmit'],
+ ],
+ ['menu_grp2', null, null,
+ ['Search Databases', '/'],
+ ['Tissue Correlation', '/webqtl/main.py?FormID=tissueCorrelation'],
+ ['SNP Browser', '/webqtl/main.py?FormID=snpBrowser'],
+ ['Gene Wiki', '/webqtl/main.py?FormID=geneWiki'],
+ ['Interval Analyst', '/webqtl/main.py?FormID=intervalAnalyst'],
+ ['QTLminer', '/webqtl/main.py?FormID=qtlminer'],
+ ['GenomeGraph', '/dbResults.html'],
+ ['Trait Collections',null,null,
+%s
+ ],
+ ['Scriptable Interface', '/CGIDoc.html'],
+ /* ['Simple Query Interface', '/GUI.html'], */
+ ['Database Information',null,null,
+ ['Database Schema', '/webqtl/main.py?FormID=schemaShowPage'],
+ ],
+ ['Data Sharing', '/webqtl/main.py?FormID=sharing'],
+ ['Microarray Annotations', '/webqtl/main.py?FormID=annotation'],
+ ],
+ ['menu_grp3', null, null,
+ ['Movies','http://www.genenetwork.org/tutorial/movies'],
+ ['Tutorials', null, null,
+ ['GN Barley Tutorial','/tutorial/pdf/GN_Barley_Tutorial.pdf'],
+ ['GN Powerpoint', '/tutorial/ppt/index.html']],
+ ['HTML Tour','/tutorial/WebQTLTour/'],
+ ['FAQ','/faq.html'],
+ ['Glossary of Terms','/glossary.html'],
+ ['GN MediaWiki','http://wiki.genenetwork.org/'],
+ ],
+ ['menu_grp4', '/whats_new.html'
+ ],
+ ['menu_grp5', '/reference.html'
+ ],
+ ['menu_grp6', null, null,
+ ['Conditions and Limitation', '/conditionsofUse.html'],
+ ['Data Sharing Policy', '/dataSharing.html'],
+ ['Status and Contacts', '/statusandContact.html'],
+ ['Privacy Policy', '/privacy.html'],
+ ],
+ ['menu_grp8', '/links.html'
+ ],
+];
+"""
+
+# create menu_items.js file
+fileHandler = open(path2 + '/menu_items.js', 'w')
+fileHandler.write(jstext % collectionsText)
+fileHandler.close()
diff --git a/web/webqtl/management/GenoUpdate.py b/web/webqtl/management/GenoUpdate.py
new file mode 100755
index 00000000..6ee87dec
--- /dev/null
+++ b/web/webqtl/management/GenoUpdate.py
@@ -0,0 +1,1279 @@
+"""
+Maintainnce module. Update Genotype data, user can update the Marker
+one by one through web interface, or batch update one Population
+through submit genotype file
+"""
+
+import string
+import os
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from utility import webqtlUtil
+from dbFunction import webqtlDatabaseFunction
+
+
+
+"""
+The Fields of Geno, GenoXRef table that be shown to user for updating
+"""
+MarkerSpeciesInfoField = ['Name', 'Chr', 'Mb', 'Sequence', 'Source']
+MarkerGroupInfoField = ['cM', 'Used_for_mapping']
+MarkerInfoField = MarkerSpeciesInfoField + MarkerGroupInfoField
+markerName_Feild_Separator = '_and_'
+
+
+# retrieve all of the Inbred Set names and group them by Species
+def retrieveSpeciesInbredSetGroup(cursor):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ rtype: dictionary
+ return: dictionary, the key are the name of Species, the value are
+ the InbredSet Names that related with the Species
+ """
+
+ SpeciesInbredSet={}
+ cursor.execute("""
+ SELECT
+ Species.Id, Species.Name
+ FROM
+ Species, InbredSet
+ WHERE
+ Species.Id=InbredSet.SpeciesId AND
+ MappingMethodId = 1
+ GROUP BY
+ Species.Id
+ """)
+ species=cursor.fetchall()
+
+ for item in species:
+ SpeciesId, SpeciesName = item
+ cursor.execute("SELECT distinct(InbredSet.Name) FROM InbredSet, GenoFreeze, GenoXRef WHERE SpeciesId=%d and GenoFreeze.InbredSetId = InbredSet.Id and GenoXRef.GenoFreezeId = GenoFreeze.Id and GenoXRef.Used_for_mapping='Y' " % SpeciesId)
+ InbredSetNames=cursor.fetchall()
+
+ InbredSetNameList=[]
+ for InbredSetName in InbredSetNames:
+ if InbredSetName[0]=='BXD300':
+ continue
+ InbredSetNameList.append(InbredSetName[0])
+ SpeciesInbredSet[SpeciesName]=InbredSetNameList
+
+ return SpeciesInbredSet
+
+
+#XZ: This function will be called in many places.
+# Each caller might organize the result in different way.
+# So the raw database results are returned.
+def retrieveGenoCode(cursor, InbredSetName):
+
+ cursor.execute("""
+ SELECT
+ AlleleType, AlleleSymbol, DatabaseValue
+ FROM
+ GenoCode, InbredSet
+ WHERE
+ InbredSet.Name = '%s' AND
+ InbredSetId = InbredSet.Id
+ """ % InbredSetName )
+ results = cursor.fetchall()
+
+ GenoCode = []
+
+ for one_result in results:
+ GenoCode.append(one_result)
+
+ return GenoCode
+
+
+def retrieveGeneticTypeOfInbredSet(cursor, InbredSetName):
+
+ GeneticType = ''
+
+ cursor.execute("""
+ SELECT
+ GeneticType
+ FROM
+ InbredSet
+ WHERE
+ InbredSet.Name=%s
+ """, InbredSetName)
+ result=cursor.fetchone()
+
+ if result:
+ GeneticType = result[0]
+
+ return GeneticType
+
+
+
+
+#XZ: For one group, retrieve the list of all strains that are in StrainXRef and used for mapping
+def retrieveStrainUsedForMapping(cursor, GroupName):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type GroupName: string
+ @param GroupName: In MySQL table, it's called Inbred Set name, in GeneNetwork's Homepage, it's called group
+
+ @rtype: list
+ @return: The Strain's names that related with the Inbred Set
+ """
+
+ cursor.execute("""
+ SELECT
+ Strain.Name
+ FROM
+ Strain, StrainXRef, InbredSet
+ WHERE
+ InbredSet.Name = '%s' AND
+ StrainXRef.InbredSetId=InbredSet.Id AND
+ StrainXRef.StrainId = Strain.Id AND
+ StrainXRef.Used_for_mapping = 'Y'
+ ORDER BY
+ StrainXRef.OrderId
+ """ % GroupName)
+ results = cursor.fetchall()
+
+ StrainList=[]
+ for item in results:
+ StrainList.append(item[0])
+
+ return StrainList
+
+
+#XZ: For one group, retrieve the dictionary of all strain id, name pairs that are in StrainXRef and used for mapping
+def retrieveStrainNameIdUsedForMapping(cursor, GroupName):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type GroupName: string
+ @param GroupName: In MySQL table, it's called Inbred Set name, in GeneNetwork's Homepage, it's called group
+
+ @rtype: dictionary
+ @return: dictionary, the key is Strain's name, the value is Strain's Id
+ """
+
+ StrainNameId = {}
+
+ cursor.execute("""
+ SELECT
+ Strain.Name, Strain.Id
+ FROM
+ Strain, StrainXRef, InbredSet
+ WHERE
+ InbredSet.Name = '%s' AND
+ StrainXRef.InbredSetId=InbredSet.Id AND
+ StrainXRef.StrainId = Strain.Id AND
+ StrainXRef.Used_for_mapping = 'Y'
+ ORDER BY
+ StrainXRef.OrderId
+ """ % GroupName)
+ results = cursor.fetchall()
+
+ for item in results:
+ StrainNameId[item[0]] = item[1]
+
+ return StrainNameId
+
+
+
+# retrieve the strain's id by name, the Strain should bind with Inbred Set
+#if the strain's name cann't be found, the id will be set to 'None'
+def retrieveStrainIds(cursor, StrainList, InbredSetName):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type StrainList: list
+ @param StrainList: the list of Strains' Name
+ @type InbredSetName: string
+
+ @rtype: dictionary
+ @return: dictionary, the key is Strain's name, the value is Strain's Id
+ """
+
+ StrainIds={}
+ for Strain in StrainList:
+ cursor.execute("""
+ SELECT
+ Strain.Id
+ FROM
+ Strain,StrainXRef,InbredSet
+ WHERE
+ Strain.Id=StrainXRef.StrainId AND
+ StrainXRef.InbredSetId=InbredSet.Id AND
+ Strain.Name=%s AND
+ InbredSet.Name=%s
+ """, (Strain, InbredSetName))
+ result=cursor.fetchone()
+ if result:
+ StrainIds[Strain]=result[0]
+ else:
+ StrainIds[Strain]=None
+
+ return StrainIds
+
+
+
+# retrieve the GenoFreezeId
+def retrieveGenoFreezeId(cursor, InbredSetName):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type InbredSetName: string
+
+ @rtype: int
+ @return: the GenoFreezeId related with the Inbred Set's name
+ """
+
+ cursor.execute("""
+ SELECT
+ GenoFreeze.Id
+ FROM
+ InbredSet, GenoFreeze
+ WHERE
+ GenoFreeze.InbredSetId=InbredSet.Id AND
+ InbredSet.Name=%s
+ """, InbredSetName)
+ result=cursor.fetchone()
+
+ if result:
+ return result[0]
+ else:
+ return None
+
+
+# retrieve the DataId
+def retrieveDataId(cursor, GenoId, InbredSetName):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type GenoId: int
+ @type InbredSetName: int
+
+ @rtype: int
+ @return: the DataId relate with the Geno(Marker) and the Inbred Set
+ """
+
+ cursor.execute("""
+ SELECT
+ GenoXRef.DataId
+ FROM
+ GenoXRef, GenoFreeze, InbredSet
+ WHERE
+ GenoXRef.GenoFreezeId=GenoFreeze.Id AND
+ GenoFreeze.InbredSetId=InbredSet.Id AND
+ GenoXRef.GenoId=%s AND
+ InbredSet.Name=%s
+ """, (GenoId, InbredSetName))
+ result=cursor.fetchone()
+
+ if result:
+ return result[0]
+ else:
+ return None
+
+
+# retrieve the max Id from GenoData table
+def retrieveMaxGenoDataId(cursor):
+ """
+ @type cursor: MySQLdb.connect.cursor
+
+ @rtype: int
+ @return: the maximal Id of the Data table
+ """
+
+ cursor.execute('SELECT max(Id) FROM GenoData')
+ results = cursor.fetchone()
+
+ return results[0]
+
+
+# retrieve the max Id from Geno table
+def retrieveMaxGenoId(cursor):
+ """
+ @type cursor: MySQLdb.connect.cursor
+
+ @rtype: int
+ @return: the maximal Id of the Geno table
+ """
+
+ cursor.execute('SELECT max(Id) FROM Geno')
+ results = cursor.fetchone()
+
+ return results[0]
+
+
+# retrieve the strain names related with a data.Id
+# Note that for one group, even if one strain is labelled as Used_for_mapping in StrainXRef table,
+# if the allele value for this strain is unknown, there is no record for this strain along with this group in GenoData table.
+# So the list of strains returned by this function <= list of strains returned by function retrieveStrainUsedForMapping.
+def retrieveDataStrains(cursor, DataId):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type DataId: int
+
+ @rtype: list
+ @return: the names list of the Strains that related with the DataId
+ """
+
+ cursor.execute("SELECT Strain.Name FROM Strain, GenoData WHERE GenoData.StrainId=Strain.Id AND GenoData.Id=%s", DataId)
+ results=cursor.fetchall()
+
+ Strains=[]
+ for item in results:
+ Strains.append(item[0])
+
+ return Strains
+
+
+
+def retrieveMarkerNameForGroupByRange(cursor, InbredSetName, Chr, MbStart, MbEnd):
+
+ MarkerName = []
+
+ SpeciesId = webqtlDatabaseFunction.retrieveSpeciesId(cursor, InbredSetName)
+
+ GenoFreezeId = retrieveGenoFreezeId(cursor, InbredSetName)
+
+ MbStartClause = ''
+ MbEndClause = ''
+
+ try:
+ MbStartClause = 'and Mb >= %s ' % float(MbStart)
+ except:
+ pass
+
+ try:
+ MbEndClause = 'and Mb <= %s' % float(MbEnd)
+ except:
+ pass
+
+
+ cmd = "SELECT Geno.Name FROM Geno, GenoXRef WHERE Geno.SpeciesId=%s and Chr='%s' " % (SpeciesId, Chr) + MbStartClause + MbEndClause + " and GenoXRef.GenoFreezeId=%s and GenoXRef.GenoId=Geno.Id and GenoXRef.Used_for_mapping='Y' order by Mb" % (GenoFreezeId)
+
+ cursor.execute(cmd)
+
+ results = cursor.fetchall()
+ for one_result in results:
+ MarkerName.append( one_result[0] )
+
+ return MarkerName
+
+
+
+# retrive the Marker's infomation from Geno and GenoXRef table,
+# the information includes the Id of the marker matchs and all of the MarkerInfoField that defined upper
+def retrieveMarkerInfoForGroup(cursor, MarkerName, InbredSetName):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type MarkerName: string
+
+ @rtype: list
+ @return: the Marker's Id, Name, Chr, cM, Mb, Sequence, Source
+ """
+
+
+ SpeciesId = webqtlDatabaseFunction.retrieveSpeciesId(cursor, InbredSetName)
+
+ GenoFreezeId = retrieveGenoFreezeId(cursor, InbredSetName)
+
+ cmd = ','.join( MarkerInfoField )
+ cmd = "SELECT Geno.Id," + cmd + " FROM Geno, GenoXRef WHERE Geno.SpeciesId=%s and Geno.Name='%s' and GenoXRef.GenoFreezeId=%s and GenoXRef.GenoId=Geno.Id" % (SpeciesId, MarkerName, GenoFreezeId)
+ cursor.execute(cmd)
+ result = cursor.fetchone()
+
+ if result:
+ return result
+ else:
+ return None
+
+
+def retrieveMarkerPositionForSpecies(cursor, GenoId):
+
+ Chr = ''
+ Mb = ''
+
+ cursor.execute( "select Chr, Mb from Geno where Id=%s" % GenoId )
+ result = cursor.fetchone()
+
+ Chr = result[0]
+ Mb = result[1]
+
+ return Chr, Mb
+
+
+def checkIfMarkerInSpecies (cursor, MarkerName, InbredSetName):
+
+ cmd = "SELECT Geno.Id FROM Geno, InbredSet, Species WHERE Geno.SpeciesId=Species.Id AND Geno.Name='%s' and InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % (MarkerName, InbredSetName)
+ cursor.execute(cmd)
+ result = cursor.fetchone()
+
+ if result:
+ return result
+ else:
+ return None
+
+
+
+
+# retrive the Marker's Used_for_mapping status from MySQL
+# for one marker, if we want it be contains in the special genotype file, we can set its value in Used_for_mapping column to 'Y' in the GenoXRef table.
+# In GenoXRef table, the default value of column Used_for_mapping is 'N'.
+# GenoXRef table is the relationship of the Marker and the allele value that this marker in special genotype
+def mappingForThisGroup(cursor, GenoFreezeId, GenoId):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type MarkerName: string
+ @type InbredSetName: string
+
+ @rtype: boolean
+ @return: the status that if the marker's exprssion value in special Inbred Set will be hide(not shown in genotype file)
+ """
+
+ cursor.execute("""
+ SELECT
+ Used_for_mapping
+ FROM
+ GenoXRef
+ WHERE
+ GenoFreezeId = %s AND
+ GenoId = %s
+ """, (GenoFreezeId, GenoId))
+ result = cursor.fetchone()
+
+ Used_for_mapping = False
+ if result:
+ if result[0] == 'Y':
+ Used_for_mapping = True
+
+ return Used_for_mapping
+
+
+# Retrieve the allele values of a Marker in specific genotype
+#
+# 1. Retrieve strain name and allele value from GenoData table
+# 2. Put the result into dictionary, the key is strain name. The value is allele (-1, 0, 1).
+#
+# Note even one strain is used for mapping for one group in GenoXRef table. When its genotype is unknown,
+# it has no record in GenoData table (e.g., BXD102 strain for marker rs6376963).
+# In this case, the dictionary key doesn't include this strain.
+def retrieveAllele (cursor, GenoFreezeId, GenoId):
+ """
+ @type cursor: MySQLdb.connect.cursor
+ @type MarkerName: string
+ @type InbredSetName: string
+
+ @rtype: dictionary
+ @return: dictionary, the keys are strain names, the values are alleles
+ that the Marker in specials Inbred Set
+ """
+
+ Alleles = {}
+
+ #retrieve the strains' name and their allele values
+ cursor.execute("""
+ SELECT
+ Strain.Name, GenoData.Value
+ FROM
+ Strain, GenoData, GenoXRef
+ WHERE
+ GenoXRef.GenoFreezeId=%s AND
+ GenoXRef.GenoId=%s AND
+ GenoXRef.DataId=GenoData.Id AND
+ GenoData.StrainId=Strain.Id
+ """, (GenoFreezeId, GenoId))
+ results = cursor.fetchall()
+
+ # set the allele value of the strain that appears in Data to the value from Data
+ for item in results:
+ Alleles[item[0]]=item[1]
+
+ return Alleles
+
+
+
+def retrieveGroupNeedExported (cursor, GenoId):
+
+ Groups = []
+
+ cursor.execute("""
+ SELECT
+ InbredSet.Name
+ FROM
+ InbredSet, GenoFreeze, GenoXRef
+ WHERE
+ Used_for_mapping = 'Y' AND
+ GenoXRef.GenoId = %s AND
+ GenoXRef.GenoFreezeId = GenoFreeze.Id AND
+ GenoFreeze.InbredSetId = InbredSet.Id
+ """, (GenoId) )
+ results = cursor.fetchall()
+
+ if results:
+ for one_result in results:
+ Groups.append( one_result[0] )
+
+ return Groups
+
+
+def get_chr_num (cursor, Chr='', SpeciesId=0):
+
+ chr_num = 99
+
+ cmd = "SELECT OrderId FROM Chr_Length WHERE Name='%s' and SpeciesId=%s " % (Chr, SpeciesId)
+
+ cursor.execute(cmd)
+ result = cursor.fetchone()
+
+ if result:
+ chr_num = result[0]
+
+ return chr_num
+
+
+
+def addGeno(cursor, GenoId, InbredSetName, MarkerWebID, fd):
+
+ SpeciesId = webqtlDatabaseFunction.retrieveSpeciesId(cursor, InbredSetName)
+
+ Name = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Name' )
+ Chr = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Chr' )
+ Mb = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Mb' )
+ Sequence = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Sequence' )
+ Source = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Source' )
+
+ chr_num = get_chr_num (cursor, Chr, SpeciesId)
+
+ cmd = "INSERT INTO Geno (Id, SpeciesId, Name, Marker_Name, Chr, Mb, Sequence, Source, chr_num) VALUES (%s, %s, '%s', '%s', '%s', %s, '%s', '%s', %s )" % (GenoId, SpeciesId, Name, Name, Chr, Mb, Sequence, Source, chr_num)
+ cursor.execute(cmd)
+
+
+
+def updateGeno(cursor, GenoId, InbredSetName, MarkerWebID, fd):
+
+ SpeciesId = webqtlDatabaseFunction.retrieveSpeciesId(cursor, InbredSetName)
+
+ Chr = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Chr' )
+ cmd = "UPDATE Geno SET Chr='%s' WHERE Id=%s" % (Chr, GenoId)
+ cursor.execute(cmd)
+
+ chr_num = get_chr_num (cursor, Chr, SpeciesId)
+ cmd = "UPDATE Geno SET chr_num=%s WHERE Id=%s" % (chr_num, GenoId)
+ cursor.execute(cmd)
+
+ Mb = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Mb' )
+ cmd = "UPDATE Geno SET Mb=%s WHERE Id=%s" % (Mb, GenoId)
+ cursor.execute(cmd)
+
+ Sequence = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Sequence' )
+ cmd = "UPDATE Geno SET Sequence='%s' WHERE Id=%s" % (Sequence, GenoId)
+ cursor.execute(cmd)
+
+ Source = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Source' )
+ cmd = "UPDATE Geno SET Source='%s' WHERE Id=%s" % (Source, GenoId)
+ cursor.execute(cmd)
+
+
+def updateGenoXRef(cursor, GenoFreezeId, GenoId, MarkerWebID, fd):
+
+ cM = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'cM' )
+ cmd = "UPDATE GenoXRef SET cM=%s WHERE GenoFreezeId=%s AND GenoId=%s" % (cM, GenoFreezeId, GenoId)
+ cursor.execute(cmd)
+
+ Used_for_mapping = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Used_for_mapping')
+
+ if Used_for_mapping == 'on':
+ cmd = "UPDATE GenoXRef SET Used_for_mapping='Y' WHERE GenoFreezeId=%s AND GenoId=%s" % (GenoFreezeId, GenoId)
+ else:
+ cmd = "UPDATE GenoXRef SET Used_for_mapping='N' WHERE GenoFreezeId=%s AND GenoId=%s" % (GenoFreezeId, GenoId)
+ cursor.execute(cmd)
+
+
+
+def addGenoXRef(cursor, GenoFreezeId, GenoId, DataId, MarkerWebID, fd):
+
+ cM = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'cM')
+
+ Used_for_mapping = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Used_for_mapping')
+
+ Used_for_mapping_db_value = 'N'
+ if Used_for_mapping == 'on':
+ Used_for_mapping_db_value = 'Y'
+
+ cmd = "INSERT INTO GenoXRef (GenoFreezeId, GenoId, DataId, cM, Used_for_mapping) VALUES (%s, %s, %s, %s, '%s')" % (GenoFreezeId, GenoId, DataId, cM, Used_for_mapping_db_value)
+
+ cursor.execute(cmd)
+
+
+
+def insertGenoData(cursor, InbredSetName, DataId, MarkerWebID, fd):
+
+ StrainList = retrieveStrainUsedForMapping (cursor, InbredSetName)
+ StrainIds = retrieveStrainIds(cursor, StrainList, InbredSetName)
+
+ for Strain in StrainList:
+ if fd.formdata.has_key( MarkerWebID + markerName_Feild_Separator + Strain ):
+ value = fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + Strain )
+
+ # XZ: The legitimate values are hard coded. Should be dynamical (from database).
+ try:
+ int_value = int(float(value))
+
+ if int_value in (0, 1, -1):
+ cmd = "INSERT INTO GenoData VALUES(%d,%d,%s)"%(DataId, StrainIds[Strain], int_value)
+ cursor.execute(cmd)
+ except:
+ pass
+
+
+#XZ: This function is to compare the input position (Chr, Mb) with position in database.
+# It should be executed before update database record.
+def getAllGroupsNeedExported(cursor, GroupNeedExport=[], GenoId=0, Chr='', Mb=''):
+
+ db_Chr, db_Mb = retrieveMarkerPositionForSpecies(cursor, GenoId)
+
+ if str(Chr) == str(db_Chr) and str(Mb) == str(db_Mb):
+ pass
+ else:
+ temp = retrieveGroupNeedExported (cursor, GenoId)
+ for one_group in temp:
+ try:
+ GroupNeedExport.index(one_group)
+ except:
+ GroupNeedExport.append(one_group)
+
+ return GroupNeedExport
+
+
+
+
+class GenoUpdate(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ # get mysql connection, if not, show error
+ if not self.openMysql():
+ heading = "Geno Updating"
+ detail = ["Can't connect to MySQL server"]
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ self.dict['title'] = 'Geno Updating'
+
+ # status is the switch, direct what's the next step
+ try:
+ status = fd.formdata.getvalue('status')
+ except:
+ status = ''
+
+ if fd.formdata.getvalue('submit')=='Clear':
+ status=''
+
+ if not status: # show
+ self.dict['body']=self.showSelectionPage()
+ elif status=='search' or status == 'addNewMarker':
+ InbredSetName = fd.formdata.getvalue('InbredSetName')
+ Chr = fd.formdata.getvalue('Chr')
+
+ if not InbredSetName:
+ self.dict['body']= "Please select the population."
+ return
+ elif not Chr:
+ self.dict['body']= "Please input Chr."
+ return
+ else:
+ self.dict['body']=self.showAllMarkers (InbredSetName, Chr, fd)
+
+ elif status == 'editMarkerTable':
+ self.dict['body'] = self.editMarkerTable(fd)
+
+ elif status == 'checkMarkerHasBeenInGroup': # check if there is anything changed.
+ InbredSetName = fd.formdata.getvalue('InbredSetName')
+ Marker = fd.formdata.getvalue('Name')
+ self.dict['body'] = self.checkMarkerHasBeenInGroup (InbredSetName, Marker, fd)
+
+ elif status=='changeMarker': #insert new marker
+ InbredSetName = fd.formdata.getvalue('InbredSetName')
+ self.dict['body']=self.changeMarker(InbredSetName, fd)
+
+ else: #this part is used to test, the proceduce won't come here in normal cycle
+ HTTable = HT.TableLite(border=0, cellspacing=1, cellpadding=1,align="center")
+ for key in fd.formdata.keys():
+ HTTable.append(HT.TR(HT.TD(key), HT.TD(':'), HT.TD(fd.formdata.getvalue(key))))
+ self.dict['body'] = HTTable
+
+
+
+
+ # this is the first page, user upload their genotype file here, or input
+ # which marker they want to update
+ def showSelectionPage(self):
+ """
+ The first page, in this page, user can upload a genotype file for batch updating,
+ or enter a Marker for one by one updating
+
+ @rtype: string
+ @return: HTML
+ """
+
+ # get the InbredSet Name list
+ SpeciesInbredSet = retrieveSpeciesInbredSetGroup(self.cursor)
+
+ # generate homepage
+
+ HTTableLite_Population = HT.TableLite(border=0, width="100%")
+
+ HTTD_InbredSet = HT.TD(width="30%")
+
+ HTSelect_InbredSetNames = HT.Select(name='InbredSetName')
+ HTSelect_InbredSetNames.append("")
+ for SpeciesName in SpeciesInbredSet.keys():
+ HT_OptGroup_Species=HT.Optgroup()
+ HT_OptGroup_Species.label=SpeciesName
+ for InbredSetName in SpeciesInbredSet[SpeciesName]:
+ HT_OptGroup_Species.append(InbredSetName)
+ HTSelect_InbredSetNames.append(HT_OptGroup_Species)
+
+ HTTD_InbredSet.append( HT.Font(HT.Strong('Group (required) '), color="red") )
+ HTTD_InbredSet.append(HTSelect_InbredSetNames)
+
+ HTTableLite_Population.append(HT.TR(HTTD_InbredSet))
+
+ HTTableLite_Marker = HT.TableLite(border=0, width="100%")
+ HTTD_Chr = HT.TD()
+ HTTD_Chr.append( HT.Font(HT.Strong('Chr (required) '), color="red") )
+ HTTD_Chr.append(HT.Input(name='Chr', size=3))
+ HTTD_Mb = HT.TD()
+ HTTD_Mb.append(HT.Font(HT.Strong('Mb')), ' from ')
+ HTTD_Mb.append(HT.Input(name='MbStart', size=10))
+ HTTD_Mb.append(' to ')
+ HTTD_Mb.append(HT.Input(name='MbEnd', size=10))
+ HTTableLite_Marker.append(HT.TR(HTTD_Chr), HT.TR(), HT.TR(HTTD_Mb) )
+
+
+
+ HTTableLite_Search = HT.TableLite(border=1, width="100%")
+ HTTableLite_Search.append(
+ HT.TR(HT.TD(HTTableLite_Population, height="100")),
+ HT.TR(HT.TD("Enter Chr and Mb range", HT.BR(), HT.BR(),
+ HTTableLite_Marker,
+ height="100"))
+ )
+
+
+ HTInput_Submit = HT.Input(type='submit', name='submit', value='Submit',Class="button")
+ HTInput_Clear = HT.Input(type='submit', name='submit', value='Clear', Class="button")
+ HTInput_FormId = HT.Input(type='hidden', name='FormID', value='updGeno')
+ HTInput_Status = HT.Input(type='hidden', name='status', value='search')
+
+ HTForm_Search = HT.Form(cgi=os.path.join(webqtlConfig.CGIDIR, 'main.py'), \
+ enctype= 'multipart/form-data', submit='')
+ HTForm_Search.append(HTTableLite_Search)
+ HTForm_Search.append(HTInput_Submit)
+ HTForm_Search.append(HTInput_Clear)
+
+ HTForm_Search.append(HTInput_FormId)
+ HTForm_Search.append(HTInput_Status)
+
+ HTTableLite_Content = HT.TableLite(border=1, width="100%")
+ HTTableLite_Content.append(HT.TR(HT.TD(HTForm_Search, width="50%"), \
+ HT.TD(HT.Font(HT.Strong("Instructions:"), HT.BR(),HT.BR(), "The \"from\" and \"to\" inputs for Mb range are optional.", HT.BR(),HT.BR(), "If only the \"from\" input is provided, the result will be all markers from the input position to the end of chromosome.", HT.BR(),HT.BR(), "If only the \"to\" input is provided, the result will be all markers from the beginning of the chromosome to the input position.", HT.BR(),HT.BR(), "If no input is provided for Mb range, the result will be all markers on the chromosome."), valign='top', width="50%") \
+ ))
+
+ return HTTableLite_Content
+
+
+
+
+ def searchMappingMarkerInDB (self, InbredSetName="", Chr='', MbStart='', MbEnd=''):
+ """
+ Show Marker's information for updating or inserting
+
+ @type InbredSetName: string
+ @type MarkerName: string
+
+ @rtype: string
+ @return: The HTML form that contains the Marker's information
+ """
+
+
+ MarkerInfoDic = {}
+
+ MarkerNamesByRange = retrieveMarkerNameForGroupByRange(self.cursor, InbredSetName, Chr, MbStart, MbEnd)
+
+ for one_MarkerName in MarkerNamesByRange:
+ one_MarkerGroupInfo = retrieveMarkerInfoForGroup (self.cursor, one_MarkerName, InbredSetName)
+ MarkerInfoDic[ one_MarkerName ] = one_MarkerGroupInfo
+
+ return MarkerNamesByRange, MarkerInfoDic
+
+
+
+ def showAllMarkers( self, InbredSetName, Chr, fd ):
+
+ MbStart = fd.formdata.getvalue('MbStart')
+ MbEnd = fd.formdata.getvalue('MbEnd')
+
+ inputStatus = fd.formdata.getvalue('status')
+
+ newMarkerNameQuantityDic = {}
+ MarkerNameAdded = []
+
+ MarkerNames, MarkerInfoDic = self.searchMappingMarkerInDB (InbredSetName=InbredSetName, Chr=Chr, MbStart=MbStart, MbEnd=MbEnd)
+
+ MainTable = HT.TableLite(border=1, cellspacing=1, cellpadding=1,align="left")
+
+ if inputStatus == 'search':
+
+
+ InputTable = HT.TableLite(border=1, cellspacing=1, cellpadding=1,align="left")
+
+ InputTable.append( HT.TR( HT.TD( HT.Textarea(name="InputNewMarker", rows=10, cols=20)),
+ HT.TD(HT.Font( "Add one input per line.", HT.BR(), HT.BR(), \
+ "Each input must be in the format of: existing marker name,quantity", HT.BR(), HT.BR(), \
+ "For instance, the input rs6376963, 2 will add two markers after rs6376963", HT.BR(), HT.BR(), \
+ "The input existing marker name must have been shown in the table below.", HT.BR(), HT.BR(), color="red"), \
+ HT.Input(type='submit', name='inputmarker_submit', value='Add new markers', Class="button", onClick= "changeStatusSubmit(this.form, 'addNewMarker');" ) ) ) )
+
+ MainTable.append( HT.TR(HT.TD(InputTable)) )
+ else:
+ InputNewMarkerString = fd.formdata.getvalue('InputNewMarker')
+
+ InputNewMarkerLines = InputNewMarkerString.split('\n')
+ for one_line in InputNewMarkerLines:
+ one_line = one_line.strip()
+ if len(one_line) > 0:
+ one_line_tokens = one_line.split(',')
+ try:
+ first_token = one_line_tokens[0].strip()
+ second_token = one_line_tokens[1].strip()
+ second_token = int( second_token )
+ if first_token in MarkerNames:
+ newMarkerNameQuantityDic[ first_token ] = second_token
+ except:
+ pass
+
+
+ MarkerTable = HT.TableLite(border=1, cellspacing=1, cellpadding=1,align="left")
+
+ HeaderRow = HT.TR()
+
+
+ for one_field in MarkerSpeciesInfoField:
+ HeaderRow.append( HT.TD(one_field) )
+
+ for one_field in MarkerGroupInfoField:
+ HeaderRow.append( HT.TD(one_field) )
+
+ GenoFreezeId = retrieveGenoFreezeId(self.cursor, InbredSetName)
+ StrainList = retrieveStrainUsedForMapping (self.cursor, InbredSetName)
+
+ for one_strain in StrainList:
+ HeaderRow.append( HT.TD(one_strain) )
+
+ MarkerTable.append( HeaderRow )
+
+
+ for one_MarkerName in MarkerNames:
+ one_MarkerGroupInfo = MarkerInfoDic[ one_MarkerName ]
+ oneMarkerRow = self.showOneMarker (InbredSetName=InbredSetName, MarkerName=one_MarkerName, suffix="", MarkerGroupInfo=one_MarkerGroupInfo, StrainList=StrainList, marker_type='existed')
+ MarkerTable.append( oneMarkerRow )
+
+ if newMarkerNameQuantityDic.has_key(one_MarkerName):
+ for i in range(0, newMarkerNameQuantityDic[one_MarkerName]):
+ MarkerNameAdded.append( one_MarkerName + '_add_' + str(i) )
+ oneMarkerRow = self.showOneMarker (InbredSetName=InbredSetName, MarkerName=one_MarkerName, suffix='_add_' + str(i), MarkerGroupInfo=one_MarkerGroupInfo, StrainList=StrainList, marker_type='add')
+ MarkerTable.append( oneMarkerRow )
+
+
+
+ MarkerTable.append( HT.TR(HT.TD( HT.Input(type='submit', name='markertable_submit', value='Edit marker table',Class="button", onClick= "changeStatusSubmit(this.form, 'editMarkerTable');") )) )
+
+ MainTable.append( HT.TR(HT.TD(MarkerTable)) )
+
+
+ HTInput_Submit = HT.Input(type='hidden', name='submit', value='Submit',Class="button")
+ HTInput_FormId = HT.Input(type='hidden', name='FormID', value='updGeno')
+ HTInput_Status = HT.Input(type='hidden', name='status', value='')
+ HTInput_InbredSetName = HT.Input(type='hidden', name='InbredSetName', value=InbredSetName)
+ HTInput_Chr = HT.Input(type='hidden', name='Chr', value=Chr)
+ HTInput_MbStart = HT.Input(type='hidden', name='MbStart', value=MbStart)
+ HTInput_MbEnd = HT.Input(type='hidden', name='MbEnd', value=MbEnd)
+ HTInput_MarkerNamesExisted = HT.Input(type='hidden', name='MarkerNamesExisted', value=','.join(MarkerNames) )
+ HTInput_MarkerNamesAdded = HT.Input(type='hidden', name='MarkerNamesAdded', value=','.join(MarkerNameAdded) )
+
+
+ HTForm_showAllMarkers = HT.Form(cgi=os.path.join(webqtlConfig.CGIDIR, 'main.py'), enctype= 'multipart/form-data', submit=HTInput_Submit)
+
+ HTForm_showAllMarkers.append( MainTable )
+ HTForm_showAllMarkers.append(HTInput_FormId)
+ HTForm_showAllMarkers.append(HTInput_Status)
+ HTForm_showAllMarkers.append(HTInput_InbredSetName)
+ HTForm_showAllMarkers.append(HTInput_Chr)
+ HTForm_showAllMarkers.append(HTInput_MbStart)
+ HTForm_showAllMarkers.append(HTInput_MbEnd)
+ HTForm_showAllMarkers.append(HTInput_MarkerNamesExisted)
+ HTForm_showAllMarkers.append(HTInput_MarkerNamesAdded)
+
+ return HTForm_showAllMarkers
+
+
+
+ def showOneMarker (self, InbredSetName="", MarkerName="", suffix="", MarkerGroupInfo=[], StrainList=[], marker_type=''):
+
+ GenoInfo={}
+
+ #XZ: The first item of MarkerInfo is Geno.Id
+ GenoId = MarkerGroupInfo[0]
+
+ for i in range(1, len(MarkerGroupInfo)):
+ if MarkerGroupInfo[i] != None:
+ GenoInfo[ MarkerInfoField[i-1] ] = str(MarkerGroupInfo[i])
+ else:
+ GenoInfo[ MarkerInfoField[i-1] ] = ''
+
+ if GenoInfo['Used_for_mapping'] == 'Y':
+ GenoInfo['Used_for_mapping'] = True
+ else:
+ GenoInfo['Used_for_mapping'] = False
+
+
+ MarkerRow = HT.TR()
+
+ # Species level info
+ for i in range(0, len(MarkerSpeciesInfoField)):
+ if MarkerSpeciesInfoField[i] == 'Name':
+ if marker_type == 'existed':
+ MarkerRow.append( HT.TD(GenoInfo['Name']) )
+ else:
+ MarkerRow.append(HT.TD(HT.Input(name = MarkerName + suffix + markerName_Feild_Separator + MarkerSpeciesInfoField[i], size=20, maxlength=500, value=MarkerName + suffix )))
+ else:
+ MarkerRow.append(HT.TD(HT.Input(name = MarkerName + suffix + markerName_Feild_Separator + MarkerSpeciesInfoField[i], size=10, maxlength=500, value=GenoInfo[MarkerSpeciesInfoField[i]])))
+
+ # Group level info
+ for i in range(0, len(MarkerGroupInfoField)):
+ if MarkerGroupInfoField[i] != 'Used_for_mapping':
+ MarkerRow.append( HT.TD(HT.Input(name = MarkerName + suffix + markerName_Feild_Separator + MarkerGroupInfoField[i], size=10, value=GenoInfo[MarkerGroupInfoField[i]])))
+ else:
+ MarkerRow.append( HT.TD(HT.Input(type='checkbox', name= MarkerName + suffix + markerName_Feild_Separator + 'Used_for_mapping', checked=GenoInfo['Used_for_mapping'] )))
+
+ # retrive Marker allele values
+ GenoFreezeId = retrieveGenoFreezeId(self.cursor, InbredSetName)
+ Alleles = retrieveAllele (self.cursor, GenoFreezeId, GenoId)
+
+ for i in range(0, len(StrainList)):
+ try:
+ Value = Alleles[StrainList[i]]
+ except:
+ Value = 'X' # 'X' is the symbol for unknown allele
+ MarkerRow.append( HT.TD(HT.Input(name = MarkerName + suffix + markerName_Feild_Separator + StrainList[i], size=3, maxlength=5, value=Value)))
+
+
+ return MarkerRow
+
+
+ def editMarkerTable (self, fd):
+
+ InbredSetName = fd.formdata.getvalue('InbredSetName')
+ Chr = fd.formdata.getvalue('Chr')
+
+ MbStart = fd.formdata.getvalue('MbStart')
+ MbEnd = fd.formdata.getvalue('MbEnd')
+
+ MarkerNamesExistedString = fd.formdata.getvalue('MarkerNamesExisted')
+ MarkerNamesAddedString = fd.formdata.getvalue('MarkerNamesAdded')
+
+ MarkerNamesExisted = []
+ MarkerNamesAdded = []
+
+ MarkerNamesExistedString = MarkerNamesExistedString.strip()
+ MarkerNamesExisted = MarkerNamesExistedString.split(',')
+
+ MarkerNamesAddedString = MarkerNamesAddedString.strip()
+ if MarkerNamesAddedString:
+ MarkerNamesAdded = MarkerNamesAddedString.split(',')
+
+ GroupNeedExport = []
+ # To simplify the business logic, just add this group to the list anyway
+ GroupNeedExport.append(InbredSetName)
+
+
+ for one_marker in MarkerNamesExisted:
+ if self.checkMarkerHasBeenInGroup(InbredSetName=InbredSetName, MarkerName=one_marker, fd=fd):
+ GroupNeedExport = self.changeMarker( InbredSetName=InbredSetName, MarkerWebID=one_marker, MarkerName=one_marker, GroupNeedExport=GroupNeedExport, fd=fd)
+
+ if MarkerNamesAdded:
+ for one_marker in MarkerNamesAdded:
+ input_name = fd.formdata.getvalue( one_marker + markerName_Feild_Separator + 'Name' )
+ GroupNeedExport = self.changeMarker( InbredSetName=InbredSetName, MarkerWebID=one_marker, MarkerName=input_name, GroupNeedExport=GroupNeedExport, fd=fd)
+
+ export_info = self.exportAllGenoFiles( GroupNeedExport )
+
+ contents = []
+
+ contents.append(export_info)
+
+ HTInput_FormId = HT.Input(type='hidden', name='FormID', value='updGeno')
+ HTInput_Back = HT.Input(type="submit", name="backButton", value="Back to main page", Class="button")
+ HTForm_Back = HT.Form(name='StrainForm', cgi=os.path.join(webqtlConfig.CGIDIR, 'main.py'), \
+ enctype= 'multipart/form-data', submit=HTInput_Back)
+ HTForm_Back.append(HTInput_FormId)
+
+ contents.append(str(HTForm_Back))
+
+ return ' '.join(contents)
+
+ # return "%s" % export_info
+
+
+
+ def checkMarkerHasBeenInGroup(self, InbredSetName="", MarkerName="", fd=None):
+
+ isChanged = False
+
+ # retrive Marker information from database
+ MarkerGroupInfo = retrieveMarkerInfoForGroup (self.cursor, MarkerName, InbredSetName)
+
+ GenoId = MarkerGroupInfo[0]
+
+ GenoInfo={}
+
+ for i in range(1, len(MarkerGroupInfo)):
+ if MarkerGroupInfo[i] != None:
+ GenoInfo[MarkerInfoField[i-1]] = str( MarkerGroupInfo[i] )
+ else:
+ GenoInfo[MarkerInfoField[i-1]] = ''
+
+ if GenoInfo['Used_for_mapping'] == 'Y':
+ GenoInfo['Used_for_mapping'] = True
+ else:
+ GenoInfo['Used_for_mapping'] = False
+
+
+ # check the changing of Geno information
+
+ for i in range(0, len(MarkerInfoField)):
+
+ if MarkerInfoField[i] == 'Name':
+ continue
+
+ webInputValue = fd.formdata.getvalue( MarkerName + markerName_Feild_Separator + MarkerInfoField[i] )
+
+
+ if MarkerInfoField[i] == 'Used_for_mapping':
+ if webInputValue == 'on':
+ webInputValue = True
+ else:
+ webInputValue = False
+
+
+ if GenoInfo[MarkerInfoField[i]] != webInputValue:
+ isChanged = True
+
+ # retrive Marker alleles
+ GenoFreezeId = retrieveGenoFreezeId(self.cursor, InbredSetName)
+ db_alleles = retrieveAllele (self.cursor, GenoFreezeId, GenoId)
+ StrainList = retrieveStrainUsedForMapping (self.cursor, InbredSetName)
+
+
+ # check the changing of allele values
+
+ for i in range(0, len(StrainList)):
+ webInputValue = fd.formdata.getvalue(MarkerName + markerName_Feild_Separator + StrainList[i])
+
+ if not db_alleles.has_key(StrainList[i]):
+ #XZ: This is hard coded.
+ #XZ: The best way is to check if the input value is in ('B', 'D', 'H').
+ if webInputValue.upper() != 'X': # 'X' is the symbol for unknown allele.
+ isChanged = True
+ else:
+ if str( db_alleles[StrainList[i]]) != webInputValue:
+ isChanged = True
+
+
+ return isChanged
+
+
+ def changeMarker(self,InbredSetName="", MarkerWebID="", MarkerName="", GroupNeedExport=[], fd=None):
+
+ GenoFreezeId = retrieveGenoFreezeId( self.cursor, InbredSetName )
+
+ MarkerGroupInfo = retrieveMarkerInfoForGroup(self.cursor, MarkerName, InbredSetName)
+
+ # This marker has record for this group.
+ # Need to keep the original GeneId and marker name.
+ if MarkerGroupInfo:
+
+ #XZ: The first item of MarkerInfo is Geno.Id
+ GenoId = MarkerGroupInfo[0]
+
+ #This function should be excuted before update Chr and Mb in database.
+ GroupNeedExport = getAllGroupsNeedExported(self.cursor, GroupNeedExport=GroupNeedExport, GenoId=GenoId, \
+ Chr=fd.formdata.getvalue(MarkerWebID + markerName_Feild_Separator + 'Chr'), \
+ Mb=fd.formdata.getvalue(MarkerWebID + markerName_Feild_Separator + 'Mb') )
+
+ # Update the info in Geno (Chr, Mb, Sequence, Source).
+ updateGeno(self.cursor, GenoId, InbredSetName, MarkerWebID, fd)
+
+ # Update GenoXRef (cM, Used_for_mapping)
+ updateGenoXRef(self.cursor, GenoFreezeId, GenoId, MarkerWebID, fd)
+
+ # Keep the original GenoXRef.DataId value.
+ DataId = retrieveDataId(self.cursor, GenoId, InbredSetName)
+
+ # Delete the original alleles
+ cmd = "delete from GenoData where Id=%s" % DataId
+ self.cursor.execute(cmd)
+
+ # Insert new alleles.
+ insertGenoData(cursor=self.cursor, InbredSetName=InbredSetName, DataId=DataId, MarkerWebID=MarkerWebID, fd=fd)
+
+ else: # No record for this group.
+
+ hasInfoForSpecies = checkIfMarkerInSpecies(self.cursor, MarkerName, InbredSetName)
+
+ if hasInfoForSpecies:
+
+ # Keep the original GenoId.
+ GenoId = hasInfoForSpecies[0]
+
+ #This function should be excuted before update Chr and Mb in database.
+ GroupNeedExport = getAllGroupsNeedExported(self.cursor, GroupNeedExport=GroupNeedExport, GenoId=GenoId, \
+ Chr=fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Chr' ), \
+ Mb=fd.formdata.getvalue( MarkerWebID + markerName_Feild_Separator + 'Mb') )
+
+
+ # Update the info in Geno (Chr, Mb, Sequence, Source).
+ updateGeno(self.cursor, GenoId, InbredSetName, MarkerWebID, fd)
+
+
+ # Get new GenoData.Id
+ DataId = retrieveMaxGenoDataId(self.cursor) + 1
+
+ # Add record in GenoXRef table for this group.
+ addGenoXRef(self.cursor, GenoFreezeId, GenoId, DataId, MarkerWebID, fd)
+
+ # Add record in GenoData table.
+ insertGenoData(cursor=self.cursor, InbredSetName=InbredSetName, DataId=DataId, MarkerWebID=MarkerWebID, fd=fd)
+
+ else:
+ # Get new Geno.Id
+ GenoId = retrieveMaxGenoId(cursor=self.cursor) + 1
+
+ # Add record in Geno
+ addGeno(self.cursor, GenoId, InbredSetName, MarkerWebID, fd)
+
+ # Get new GenoData.Id
+ DataId = retrieveMaxGenoDataId(self.cursor) + 1
+
+ # Add record into GenoXRef table.
+ addGenoXRef(self.cursor, GenoFreezeId, GenoId, DataId, MarkerWebID, fd)
+
+ #Add record into GenoData table.
+ insertGenoData(cursor=self.cursor, InbredSetName=InbredSetName, DataId=DataId, MarkerWebID=MarkerWebID, fd=fd)
+
+ return GroupNeedExport
+
+
+
+ def exportAllGenoFiles (self, InbredSetNameList = []):
+
+ warning = "As to the change made, the following groups need to be exported to generate new geno files: %s\n
" % str(InbredSetNameList)
+
+ whiteList = ['BXD']
+
+ warning = warning + "At current development stage, the following groups can be exported to generate geno files: %s\n
" % str(whiteList)
+ warning = warning + "Here are the geno files that are ACTUALLY exported according to the change you made:\n "
+
+ blackList = []
+ for one_group in InbredSetNameList:
+ if one_group in whiteList:
+ self.exportOneGenoFile( one_group )
+ warning = warning + "" + one_group + " geno file\n "
+ else:
+ blackList.append(one_group)
+
+ return warning
+
+
+
+ def exportOneGenoFile (self, InbredSetName=''):
+
+ geno_file = open(webqtlConfig.GENODIR + InbredSetName + '.geno', 'w')
+
+ query = "select SpeciesId from InbredSet where Name='%s' " % InbredSetName
+ self.cursor.execute( query )
+ SpeciesId = self.cursor.fetchone()[0]
+
+ GenoFreezeId = retrieveGenoFreezeId( self.cursor, InbredSetName )
+
+ StrainUsedForMapping = retrieveStrainUsedForMapping(self.cursor, InbredSetName )
+
+ StrainNameIdUsedForMapping = retrieveStrainNameIdUsedForMapping( self.cursor, InbredSetName )
+
+ GenoCode_record = retrieveGenoCode(self.cursor, InbredSetName )
+
+ Allle_value_symbol = {}
+ symbol_for_unknown = ''
+
+ for one_result in GenoCode_record:
+ if str(one_result[2]) != 'None':
+ Allle_value_symbol[one_result[2]] = one_result[1]
+ else:
+ symbol_for_unknown = one_result[1]
+
+
+ geno_file.write('@name:%s\n' % InbredSetName )
+
+ GeneticType = retrieveGeneticTypeOfInbredSet(self.cursor, InbredSetName )
+
+ geno_file.write('@type:%s\n' % str(GeneticType) )
+
+ for one_result in GenoCode_record:
+ geno_file.write('@%s:%s\n' % (one_result[0], one_result[1]) )
+
+ geno_file.write('Chr\tLocus\tcM\tMb')
+
+ for one_strain in StrainUsedForMapping:
+ geno_file.write('\t%s' % one_strain )
+
+
+ query = "select Geno.Chr, Geno.Name, GenoXRef.cM, Geno.Mb, GenoXRef.DataId from Geno, GenoXRef where SpeciesId=%s and GenoFreezeId=%s and Used_for_mapping='Y' and Geno.Id=GenoId order by chr_num, Mb" % (SpeciesId, GenoFreezeId)
+ self.cursor.execute( query )
+ results = self.cursor.fetchall()
+
+ StrainId_Allele = {}
+
+ for one_result in results:
+ Chr, Name, cM, Mb, DataId = one_result
+ geno_file.write('\n%s\t%s\t%s\t%s' % (Chr, Name, cM, Mb) )
+
+ StrainId_Allele = {}
+
+ query = "select StrainId, value from GenoData where Id=%s " % DataId
+ self.cursor.execute( query )
+ GenoData_results = self.cursor.fetchall()
+
+ for one_GenoData_result in GenoData_results:
+ StrainId_Allele[ one_GenoData_result[0] ] = one_GenoData_result[1]
+
+ for one_strain_name in StrainUsedForMapping:
+ one_strain_id = StrainNameIdUsedForMapping[ one_strain_name ]
+
+ if StrainId_Allele.has_key( one_strain_id ):
+ one_allele_value = StrainId_Allele[one_strain_id]
+ one_allele_symbol = Allle_value_symbol[ one_allele_value ]
+ geno_file.write( '\t%s' % one_allele_symbol )
+ else:
+ geno_file.write( '\t%s' % symbol_for_unknown )
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/webqtl/management/__init__.py b/web/webqtl/management/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/management/assignUserToDatasetPage.py b/web/webqtl/management/assignUserToDatasetPage.py
new file mode 100755
index 00000000..8e089526
--- /dev/null
+++ b/web/webqtl/management/assignUserToDatasetPage.py
@@ -0,0 +1,159 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+import string
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+
+#XZ, 02/06/2009: Xiaodong created this class
+class assignUserToDatasetPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+
+ ifVerified = fd.formdata.getvalue('ifVerified')
+
+ if ifVerified != 'GN@UTHSC':
+ heading = "Error page"
+ detail = ["You are NoT verified as administrator."]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+
+ ProbeSetFreeze_FullName = fd.formdata.getvalue('ProbeSetFreeze_FullName')
+ User_name = fd.formdata.getvalue('User_name')
+
+ if ProbeSetFreeze_FullName and User_name:
+ ProbeSetFreeze_FullName = string.strip(ProbeSetFreeze_FullName)
+ User_name = string.strip(User_name)
+
+ #XZ, check if the input dataset name exists.
+ self.cursor.execute( 'select count(FullName) from ProbeSetFreeze where FullName="%s"' % ProbeSetFreeze_FullName )
+ result = self.cursor.fetchone()
+ if result:
+ row_count = result[0]
+ if row_count:
+ pass
+ else:
+ heading = "Error page"
+ detail = ["The dataset name %s does NOT exist in database." % ProbeSetFreeze_FullName]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ heading = "Error page"
+ detail = ["No sql result returned when check dataset name."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, check if the input user name exists.
+ self.cursor.execute( 'select count(name) from User where name="%s"' % User_name )
+ result = self.cursor.fetchone()
+ if result:
+ row_count = result[0]
+ if row_count:
+ pass
+ else:
+ heading = "Error page"
+ detail = ["The user name %s does NOT exist in database." % User_name]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ heading = "Error page"
+ detail = ["No sql result returned when check user name."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.cursor.execute( 'select AuthorisedUsers from ProbeSetFreeze where FullName="%s"' % ProbeSetFreeze_FullName )
+ result = self.cursor.fetchone() # The FullName is unique.
+ if result:
+ AuthorisedUsers = result[0]
+ if not AuthorisedUsers:
+ self.cursor.execute('update ProbeSetFreeze set AuthorisedUsers="%s" where FullName="%s"' %(User_name, ProbeSetFreeze_FullName) )
+ else:
+ AuthorisedUsersList=AuthorisedUsers.split(',')
+ if not AuthorisedUsersList.__contains__(User_name):
+ AuthorisedUsers = AuthorisedUsers + ',%s' % User_name
+ self.cursor.execute('update ProbeSetFreeze set AuthorisedUsers="%s" where FullName="%s"' %(AuthorisedUsers, ProbeSetFreeze_FullName) )
+ else:
+ heading = "Error page"
+ detail = ["No sql result returned when query AuthorisedUsers."]
+ self.error(heading=heading,detail=detail)
+ return
+
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ dataHeading = HT.Paragraph('Confidential Dataset Table', Class="title")
+
+ dataTable = HT.TableLite(border=1, cellpadding=0, cellspacing=0, Class="collap", width="100%")
+
+ dataHeaderRow = HT.TR()
+ dataHeaderRow.append(HT.TD("Dataset Id", Class='fs14 fwb ffl b1 cw cbrb'))
+ dataHeaderRow.append(HT.TD("Dataset Full Name", Class='fs14 fwb ffl b1 cw cbrb'))
+ dataHeaderRow.append(HT.TD("Authorised User", Class='fs14 fwb ffl b1 cw cbrb'))
+ dataTable.append(dataHeaderRow)
+
+ self.cursor.execute('select Id, FullName, AuthorisedUsers from ProbeSetFreeze where confidentiality=1 order by FullName,Id')
+
+ result = self.cursor.fetchall()
+
+ dataInfo = HT.Blockquote( 'There are %d confidential datasets.' % len(result) )
+
+
+ for one_row in result:
+ ProbeSetFreeze_Id, ProbeSetFreeze_FullName, ProbeSetFreeze_AuthorisedUsers = one_row
+ dataRow = HT.TR()
+ dataRow.append(HT.TD("%s" % ProbeSetFreeze_Id, Class='fs12 fwn ffl b1 c222'))
+ dataRow.append(HT.TD("%s" % ProbeSetFreeze_FullName, Class='fs12 fwn ffl b1 c222'))
+ dataRow.append(HT.TD("%s" % ProbeSetFreeze_AuthorisedUsers, Class='fs12 fwn ffl b1 c222'))
+ dataTable.append(dataRow)
+
+ assignUserForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='assignUserForm', submit=HT.Input(type='hidden'))
+ assignUserForm.append(
+ HT.Blockquote(
+ HT.Font('Dataset Full Name ', color='red'),
+ HT.Input(type='text' ,name='ProbeSetFreeze_FullName',value='', size=50,maxlength=200),
+ HT.Font(' User name ', color='red'),
+ HT.Input(type='text' ,name='User_name',value='', size=20,maxlength=20),
+ HT.Input(type='Submit', value='Submit', Class="button")),
+ HT.Input(type='hidden',name='FormID',value='assignUserToDataset'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+
+ TD_LR.append(dataHeading, dataInfo, assignUserForm, dataTable, assignUserForm)
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = 'Confidential datasets'
+
diff --git a/web/webqtl/management/createUserAccountPage.py b/web/webqtl/management/createUserAccountPage.py
new file mode 100755
index 00000000..f002c6ed
--- /dev/null
+++ b/web/webqtl/management/createUserAccountPage.py
@@ -0,0 +1,161 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+import string
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+
+
+
+#XZ, 02/06/2009: Xiaodong created this class
+class createUserAccountPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+
+ ifVerified = fd.formdata.getvalue('ifVerified')
+
+ if ifVerified != 'GN@UTHSC':
+ heading = "Error page"
+ detail = ["You are NoT verified as administrator."]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+
+ user_name = fd.formdata.getvalue('user_name')
+ password = fd.formdata.getvalue('password')
+ retype_password = fd.formdata.getvalue('retype_password')
+
+ if user_name or password or retype_password:
+ user_name = string.strip(user_name)
+ password = string.strip(password)
+ retype_password = string.strip(retype_password)
+
+ #XZ, check if the input user name exists.
+
+ if len(user_name) == 0:
+ heading = "Error page"
+ detail = ["The user name can NOT be empty."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.cursor.execute( 'select count(name) from User where name="%s"' % user_name )
+ result = self.cursor.fetchone()
+ if result:
+ row_count = result[0]
+ if row_count:
+ heading = "Error page"
+ detail = ["The user name %s already exists in database. Please make up another user name." % user_name]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ heading = "Error page"
+ detail = ["No sql result returned when check user name."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ # check password
+ if len(password) == 0 or len(retype_password) == 0:
+ heading = "Error page"
+ detail = ["The password can NOT be empty."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ if password != retype_password:
+ heading = "Error page"
+ detail = ["The passwords you entered are NOT consistent. Please go back and try again."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ #XZ, create new account
+ self.cursor.execute( "insert into User (name, password, createtime, privilege) values ('%s', SHA('%s'), Now(), 'user')" % (user_name, password) )
+
+
+ #show user table.
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ userHeading = HT.Paragraph('User Table', Class="title")
+
+ self.cursor.execute( 'select id, name, privilege from User order by name' )
+
+ result = self.cursor.fetchall()
+
+ userInfo = HT.Blockquote( 'There are %d users.' % len(result) )
+
+ userTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0, Class="collap", width="100%")
+
+ userHeaderRow = HT.TR()
+ userHeaderRow.append(HT.TD("User Id", Class='fs14 fwb ffl b1 cw cbrb'))
+ userHeaderRow.append(HT.TD("User name", Class='fs14 fwb ffl b1 cw cbrb'))
+ userHeaderRow.append(HT.TD("User privilege", Class='fs14 fwb ffl b1 cw cbrb'))
+ userTable.append(userHeaderRow)
+
+ for one_row in result:
+ User_Id, User_name, User_privilege = one_row
+ userRow = HT.TR()
+ userRow.append(HT.TD("%s" % User_Id, Class='fs12 fwn ffl b1 c222'))
+ userRow.append(HT.TD("%s" % User_name, Class='fs12 fwn ffl b1 c222'))
+ userRow.append(HT.TD("%s" % User_privilege, Class='fs12 fwn ffl b1 c222'))
+ userTable.append(userRow)
+
+ #add user form
+ createUserAccountForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='createUserAccountForm', submit=HT.Input(type='hidden'))
+
+ user_name = HT.Input(type='text' ,name='user_name',value='', size=20,maxlength=20)
+ password = HT.Input(type='password' ,name='password',value='', size=20,maxlength=20)
+ retype_password = HT.Input(type='password' ,name='retype_password',value='', size=20,maxlength=20)
+ submit_button = HT.Input(type='Submit', value='Submit', Class="button")
+
+ createUserAccountForm.append(
+ HT.Blockquote( HT.Font('Create one new account: User Name ', color='red'), user_name, HT.Font(' Password ', color='red'), password, HT.Font(' Retype Password ', color='red'), retype_password, submit_button ),
+ HT.Input(type='hidden',name='FormID',value='createUserAccount'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+
+ """
+ #manager form
+ managerForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='managerForm', submit=HT.Input(type='hidden'))
+ managerForm.append(
+ HT.Input(type='Submit', value='Go to manager main page', Class="button"),
+ HT.Input(type='hidden',name='FormID',value='managerMain'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+ """
+
+ #TD_LR.append(managerForm, HT.BR(), userHeading, userInfo, HT.P(), createUserAccountForm, userTable, createUserAccountForm, HT.BR(), managerForm)
+ TD_LR.append(userHeading, userInfo, HT.P(), createUserAccountForm, userTable, createUserAccountForm)
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = 'User account'
diff --git a/web/webqtl/management/deletePhenotypeTraitPage.py b/web/webqtl/management/deletePhenotypeTraitPage.py
new file mode 100755
index 00000000..de071003
--- /dev/null
+++ b/web/webqtl/management/deletePhenotypeTraitPage.py
@@ -0,0 +1,196 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from base.webqtlDataset import webqtlDataset
+from base.webqtlTrait import webqtlTrait
+
+
+#XZ, 09/07/2009: Xiaodong created this class
+class deletePhenotypeTraitPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ ifVerified = fd.formdata.getvalue('ifVerified')
+ status = fd.formdata.getvalue('status')
+
+ if ifVerified != 'GN@UTHSC':
+ heading = "Error page"
+ detail = ["You are NoT verified as administrator."]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ if status == 'input':
+ self.dict['body'] = self.genInputPage()
+ self.dict['title'] = 'Delete Phenotype Trait Input Page'
+ if status == 'check':
+ PublishFreeze_Name = fd.formdata.getvalue('PublishFreeze_Name')
+ traitID = fd.formdata.getvalue('traitID')
+ self.dict['body'] = self.checkInputPage(PublishFreeze_Name, traitID)
+ self.dict['title'] = 'Delete Phenotype Trait Check Input Page'
+ if status == 'delete':
+ PublishFreeze_Name = fd.formdata.getvalue('PublishFreeze_Name')
+ traitID = fd.formdata.getvalue('traitID')
+ self.dict['body'] = self.deleteResultPage(PublishFreeze_Name, traitID)
+ self.dict['title'] = 'Delete Phenotype Trait Result Page'
+
+
+ def genInputPage(self):
+
+ crossMenu = HT.Select(name='PublishFreeze_Name', onChange='xchange()')
+
+ self.cursor.execute('select PublishFreeze.Name from PublishFreeze, InbredSet where InbredSetId=InbredSet.Id')
+ result = self.cursor.fetchall()
+
+ for one_row in result:
+ Name = one_row
+ crossMenu.append(tuple([Name,Name]))
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ deletePhenotypeTraitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='deletePhenotypeTraitForm', submit=HT.Input(type='hidden'))
+ deletePhenotypeTraitForm.append(
+ HT.Blockquote(
+ HT.Font('Publish Freeze Name '),
+ crossMenu,
+ HT.Font(' Phenotype Trait ID '),
+ HT.Input(type='text' ,name='traitID',value='', size=20,maxlength=20),
+ HT.Input(type='Submit', value='Submit', Class="button")),
+ HT.Input(type='hidden',name='FormID',value='deletePhenotypeTrait'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC'),
+ HT.Input(type='hidden',name='status',value='check')
+ )
+
+ TD_LR.append(deletePhenotypeTraitForm)
+
+ return str(TD_LR)
+
+
+ def checkInputPage(self, PublishFreeze_Name, traitID):
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ try:
+ db = webqtlDataset(PublishFreeze_Name, self.cursor)
+ thisTrait = webqtlTrait(db=db, cursor=self.cursor, name=traitID)
+ thisTrait.retrieveInfo()
+ setDescription = thisTrait.genHTML(dispFromDatabase=1, privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users)
+ except:
+ TD_LR.append( HT.Font('This trait is not found. Please go back to check if you selected correct Group Name and inputed correct trait ID.', color='red') )
+ return str(TD_LR)
+
+ #TD_LR.append(HT.Font('Publish Freeze Name: %s' % PublishFreeze_Name, color='red'),HT.BR(), HT.Font('trait ID: %s' % traitID, color='red'), HT.BR())
+
+ formMain = HT.Form(cgi=os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='showDatabase', submit=HT.Input(type='hidden'))
+
+ formMain.append(
+ HT.Blockquote(
+ HT.Font('The trait '),
+ setDescription,
+ HT.Font(' will be deleted.'),
+ HT.BR(), HT.BR(),
+ HT.Font('Please open the trait and make sure you do want to delete it.', color = 'red')
+ ),
+ HT.Input(type='hidden',name='FormID',value=''),
+ HT.Input(type='hidden',name='database',value=''),
+ HT.Input(type='hidden',name='ProbeSetID',value=''),
+ HT.Input(type='hidden',name='CellID',value='')
+ )
+
+ deletePhenotypeTraitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='deletePhenotypeTraitForm', submit=HT.Input(type='hidden'))
+ deletePhenotypeTraitForm.append(
+ HT.Input(type='Submit', value='Delete Trait', Class="button"),
+ HT.Input(type='hidden',name='FormID',value='deletePhenotypeTrait'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC'),
+ HT.Input(type='hidden',name='status',value='delete'),
+ HT.Input(type='hidden',name='PublishFreeze_Name',value=db),
+ HT.Input(type='hidden',name='traitID',value=traitID)
+ )
+
+
+ TD_LR.append(formMain, HT.BR(), HT.BR(), deletePhenotypeTraitForm)
+ return str(TD_LR)
+
+ def deleteResultPage(self, PublishFreeze_Name, traitID):
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ #TD_LR.append(HT.Font('Publish Freeze Name: %s' % PublishFreeze_Name, color='red'),HT.BR(), HT.Font('trait ID: %s' % traitID, color='red'), HT.BR(), HT.BR(), 'Being constructed...')
+
+ self.cursor.execute( 'select InbredSetId from PublishFreeze where Name="%s"' % PublishFreeze_Name )
+ InbredSetId = self.cursor.fetchone()[0]
+ #TD_LR.append(HT.BR(), HT.BR(), 'InbredSetId: ', InbredSetId)
+
+ self.cursor.execute( 'select PhenotypeId, PublicationId, DataId from PublishXRef where Id = %s and InbredSetId = %s' % (traitID, InbredSetId) )
+ result = self.cursor.fetchone()
+ PhenotypeId, PublicationId, DataId = result
+
+ #TD_LR.append(HT.BR(), 'PhenotypeId: ', PhenotypeId)
+ #TD_LR.append(HT.BR(), 'PublicationId: ', PublicationId)
+ #TD_LR.append(HT.BR(), 'DataId: ', DataId)
+
+ #PublishData
+ self.cursor.execute('delete from PublishData where Id = %s' % DataId)
+
+ #PublishSE
+ self.cursor.execute('delete from PublishSE where DataId = %s' % DataId)
+
+ #NStrain
+ self.cursor.execute('delete from NStrain where DataId = %s' % DataId)
+
+ #Phenotype
+ self.cursor.execute( 'select count(*) from PublishXRef where PhenotypeId = %s' % PhenotypeId )
+ PhenotypeId_count = self.cursor.fetchone()[0]
+ #TD_LR.append(HT.BR(), HT.BR(), 'PhenotypeId_count: ', PhenotypeId_count)
+ if PhenotypeId_count > 1:
+ pass
+ else:
+ self.cursor.execute('delete from Phenotype where Id = %s' % PhenotypeId)
+
+ #Publication
+ self.cursor.execute( 'select count(*) from PublishXRef where PublicationId = %s' % PublicationId )
+ PublicationId_count = self.cursor.fetchone()[0]
+ #TD_LR.append(HT.BR(), 'PublicationId_count: ', PublicationId_count)
+ if PublicationId_count > 1:
+ pass
+ else:
+ self.cursor.execute('delete from Publication where Id = %s' % PublicationId)
+
+ #PublishXRef
+ self.cursor.execute( 'delete from PublishXRef where Id = %s and InbredSetId = %s' % (traitID, InbredSetId) )
+
+ #TD_LR.append(HT.BR(), HT.BR() )
+ TD_LR.append('The trait %s has been successfully deleted from %s' % (traitID, PublishFreeze_Name))
+
+ return str(TD_LR)
diff --git a/web/webqtl/management/editHeaderFooter.py b/web/webqtl/management/editHeaderFooter.py
new file mode 100755
index 00000000..1461fa3a
--- /dev/null
+++ b/web/webqtl/management/editHeaderFooter.py
@@ -0,0 +1,200 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from htmlgen import HTMLgen2 as HT
+import os
+import string
+import urlparse
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+
+# 20100309 Lei Yan
+class editHeaderFooter(templatePage):
+
+ htmlPath = webqtlConfig.ChangableHtmlPath
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ self.templateInclude = 1
+ self.dict['title'] = "Editing HTML"
+
+ if not self.updMysql():
+ return
+
+ path = fd.formdata.getvalue('path')
+ preview = fd.formdata.getvalue('preview')
+ newHtmlCode = fd.formdata.getvalue('htmlSrc')
+ hf = fd.formdata.getvalue('hf')
+
+ if newHtmlCode:
+ newHtmlCode = string.replace(newHtmlCode,"&", "&")
+ if path and preview:
+ self.templateInclude = 0
+ if hf=='h':
+ tempH = newHtmlCode
+ fp = open(self.htmlPath+'/footer.html', 'r')
+ tempF = fp.read()
+ fp.close()
+ else:
+ fp = open(self.htmlPath+'/header.html', 'r')
+ tempH = fp.read()
+ fp.close()
+ tempF = newHtmlCode
+ tempHtml = """
+
+Header Footer Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %s
+
+
+
+
+
+
+
+
+
Header Footer Test
+
+
+
+
+
+
+
+
+ %s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""" %(tempH, tempF)
+ self.debug = tempHtml
+ elif path:
+ #edit result
+ fileName = self.htmlPath + path
+
+ fp1 = open(fileName, 'w')
+ fp1.write(newHtmlCode)
+ fp1.close()
+
+ fp1 = open(fileName, 'r')
+ lines = fp1.readlines()
+ fp1.close
+
+ if 'h'==hf:
+ fp2 = open(self.htmlPath + '/javascript/header.js', 'w')
+ else:
+ fp2 = open(self.htmlPath + '/javascript/footer.js', 'w')
+ fp2.write("ctext = ''\r\n")
+ fp2.flush()
+ for line in lines:
+ fp2.write("ctext += '%s'\r\n" %(line.rstrip()))
+ fp2.flush()
+ fp2.write('document.write(ctext)')
+ fp2.flush()
+ fp2.close()
+
+ TD_LR = HT.TD(valign="top",colspan=2,bgcolor="#eeeeee", height=200)
+ mainTitle = HT.Paragraph("Edit HTML", Class="title")
+ url = HT.Href(text = "page", url =path, Class = "normal")
+ intro = HT.Blockquote("This ",url, " has been succesfully modified. ")
+ TD_LR.append(mainTitle, intro)
+ self.dict['body'] = TD_LR
+ elif fd.refURL:
+ #retrieve file to be edited
+ #refURL = os.environ['HTTP_REFERER']
+ addressing_scheme, network_location, path, parameters, query, fragment_identifier = urlparse.urlparse(fd.refURL)
+ if 'h'==hf:
+ path = "/header.html"
+ else:
+ path = "/footer.html"
+ fileName = self.htmlPath + path
+ fp = open(fileName,'r')
+ htmlCode = fp.read()
+ htmlCode = string.replace(htmlCode, "&","&")
+ fp.close()
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='editHtml',submit=HT.Input(type='hidden'))
+ inputBox = HT.Textarea(name='htmlSrc', cols="100", rows=30,text=htmlCode)
+ hddn = {'FormID':'editHeaderFooter', 'path':path, 'preview':'', 'hf':hf}
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+ previewButton = HT.Input(type='button',name='previewhtml', value='Preview',Class="button", onClick= "editHTML(this.form, 'preview');")
+ submitButton = HT.Input(type='button',name='submitchange', value='Submit Change',Class="button", onClick= "editHTML(this.form, 'submit');")
+ resetButton = HT.Input(type='reset',Class="button")
+ form.append(HT.Center(inputBox, HT.P(), previewButton, submitButton, resetButton))
+ TD_LR = HT.TD(valign="top",colspan=2,bgcolor="#eeeeee")
+ mainTitle = HT.Paragraph("Edit HTML", Class="title")
+ intro = HT.Blockquote("You may edit the HTML source code in the editbox below, or you can copy the content of the editbox to your favorite HTML editor. ")
+ imgUpload = HT.Href(url="javascript:openNewWin('/upload.html', 'menubar=0,toolbar=0,location=0,resizable=0,status=1,scrollbars=1,height=400, width=600');", text="here", Class="normalsize")
+ intro2 = HT.Blockquote("Click ", imgUpload, " to upload Images. ")
+ TD_LR.append(mainTitle, intro, intro2, HT.Center(form))
+ self.dict['body'] = TD_LR
+ else:
+ heading = "Editing HTML"
+ detail = ["Error occured while trying to edit the html file."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
diff --git a/web/webqtl/management/exportPhenotypeDatasetPage.py b/web/webqtl/management/exportPhenotypeDatasetPage.py
new file mode 100755
index 00000000..bbd86385
--- /dev/null
+++ b/web/webqtl/management/exportPhenotypeDatasetPage.py
@@ -0,0 +1,228 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+import string
+import pyXLWriter as xl
+import time
+
+import reaper
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base import webqtlConfig
+from base.webqtlTrait import webqtlTrait
+
+
+
+#XZ, 11/06/2009: Xiaodong created this class
+class exportPhenotypeDatasetPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ ifVerified = fd.formdata.getvalue('ifVerified')
+ status = fd.formdata.getvalue('status')
+
+ if ifVerified != 'GN@UTHSC':
+ heading = "Error page"
+ detail = ["You are NoT verified as administrator."]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ if status == 'input':
+ self.dict['body'] = self.genInputPage()
+ self.dict['title'] = 'Export Phenotype Dataset Input Page'
+ if status == 'output':
+ PublishFreeze_Name = fd.formdata.getvalue('PublishFreeze_Name')
+ self.dict['body'] = self.exportDatasetPage( fd, PublishFreeze_Name )
+ self.dict['title'] = 'Export Phenotype Dataset Page'
+
+
+ def genInputPage(self):
+
+ crossMenu = HT.Select(name='PublishFreeze_Name', onChange='xchange()')
+
+ self.cursor.execute('select PublishFreeze.Name from PublishFreeze, InbredSet where InbredSetId=InbredSet.Id')
+ result = self.cursor.fetchall()
+
+ for one_row in result:
+ Name = one_row
+ crossMenu.append(tuple([Name,Name]))
+
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ exportPhenotypeDatasetForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='exportPhenotypeDatasetForm', submit=HT.Input(type='hidden'))
+ exportPhenotypeDatasetForm.append(
+ HT.Blockquote(
+ HT.Font('Publish Freeze Name '),
+ crossMenu,
+ HT.Input(type='Submit', value='Submit', Class="button")),
+ HT.Input(type='hidden',name='FormID',value='exportPhenotypeDataset'),
+ HT.Input(type='hidden',name='status',value='output'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+
+ TD_LR.append( exportPhenotypeDatasetForm )
+
+ return str(TD_LR)
+
+
+ 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)
+
diff --git a/web/webqtl/management/managerMainPage.py b/web/webqtl/management/managerMainPage.py
new file mode 100755
index 00000000..36f744ad
--- /dev/null
+++ b/web/webqtl/management/managerMainPage.py
@@ -0,0 +1,130 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base import webqtlConfig
+
+#XZ, 02/06/2009: Xiaodong created this class
+class managerMainPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ ifVerified = None
+
+ ifVerified = fd.formdata.getvalue('ifVerified')
+
+ if ifVerified != 'GN@UTHSC':
+ user = fd.formdata.getvalue('user')
+ password = fd.formdata.getvalue('password')
+ privilege, user_id, userExist = webqtlUtil.authUser(user,password,self.cursor,encrypt = None)[:3]
+
+ if userExist and webqtlConfig.USERDICT[privilege] >= webqtlConfig.USERDICT['admin']:
+ ifVerified = True
+
+
+ if not ifVerified:
+ heading = "Error page"
+ detail = ["You do not have privilege to change system configuration."]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ TD_LR = HT.TD(height=200,width="100%", bgColor='#eeeeee')
+
+ heading = "Please click button to make your selection"
+
+ createUserAccountForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='createUserAccountForm', submit=HT.Input(type='hidden'))
+ createUserAccountForm.append(
+ HT.Input(type='button', name='', value='Manage User Accounts', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden',name='FormID',value='createUserAccount'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+
+ assignUserToDatasetForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='assignUserToDatasetForm', submit=HT.Input(type='hidden'))
+ assignUserToDatasetForm.append(
+ HT.Input(type='button', name='', value='Manage Confidential Datasets', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden',name='FormID',value='assignUserToDataset'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+
+ deletePhenotypeTraitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='deletePhenotypeTraitForm', submit=HT.Input(type='hidden'))
+ deletePhenotypeTraitForm.append(
+ HT.Input(type='button', name='', value='Delete Phenotype Trait', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden',name='FormID',value='deletePhenotypeTrait'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC'),
+ HT.Input(type='hidden',name='status',value='input')
+ )
+
+ exportPhenotypeDatasetForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='exportPhenotypeDatasetForm', submit=HT.Input(type='hidden'))
+ exportPhenotypeDatasetForm.append(
+ HT.Input(type='button', name='', value='Export Phenotype Dataset', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden',name='FormID',value='exportPhenotypeDataset'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC'),
+ HT.Input(type='hidden',name='status',value='input')
+ )
+
+ updateGenotypeForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='updateGenotypeForm', submit=HT.Input(type='hidden'))
+ updateGenotypeForm.append(
+ HT.Input(type='button', name='', value='Update Genotype', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden',name='FormID',value='updGeno'),
+ HT.Input(type='hidden',name='ifVerified',value='GN@UTHSC')
+ )
+
+ editHeaderForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='editHeaderForm', submit=HT.Input(type='hidden'))
+ editHeaderForm.append(
+ HT.Input(type='button', name='', value='Edit Header', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden', name='FormID', value='editHeaderFooter'),
+ HT.Input(type='hidden', name='hf', value='h'),
+ )
+
+ editFooterForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='editFooterForm', submit=HT.Input(type='hidden'))
+ editFooterForm.append(
+ HT.Input(type='button', name='', value='Edit Footer', Class="button", onClick="submitToNewWindow(this.form);"),
+ HT.Input(type='hidden', name='FormID', value='editHeaderFooter'),
+ HT.Input(type='hidden', name='hf', value='f'),
+ )
+
+ TD_LR.append(heading, HT.P(),HT.P(),
+ createUserAccountForm, HT.P(),HT.P(),
+ assignUserToDatasetForm, HT.P(),HT.P(),
+ deletePhenotypeTraitForm, HT.P(),HT.P(),
+ exportPhenotypeDatasetForm, HT.P(),HT.P(),
+ updateGenotypeForm, HT.P(),HT.P(),
+ editHeaderForm, HT.P(),HT.P(),
+ editFooterForm)
+
+ self.dict['body'] = str(TD_LR)
+ self.dict['title'] = 'Manager Main Page'
+
diff --git a/web/webqtl/markerRegression/CompositeMarkerRegressionPage.py b/web/webqtl/markerRegression/CompositeMarkerRegressionPage.py
new file mode 100755
index 00000000..6cd8c53a
--- /dev/null
+++ b/web/webqtl/markerRegression/CompositeMarkerRegressionPage.py
@@ -0,0 +1,211 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import string
+import piddle as pid
+import os
+
+from htmlgen import HTMLgen2 as HT
+import reaper
+
+from utility import Plot
+from base.templatePage import templatePage
+from base import webqtlConfig
+from utility import webqtlUtil
+
+
+
+class CompositeMarkerRegressionPage(templatePage):
+
+ 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 GenReport(self, fd, _genotype, _strains, _vals, _vars= []):
+ 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.'
+ if webqtlUtil.ListNotNull(_vars):
+ qtlresults = _genotype.regression(strains = _strains, trait = _vals, variance = _vars, control = self.controlLocus)
+ LRSArray = _genotype.permutation(strains = _strains, trait = _vals, variance = _vars, nperm=fd.nperm)
+ else:
+ qtlresults = _genotype.regression(strains = _strains, trait = _vals, control = self.controlLocus)
+ LRSArray = _genotype.permutation(strains = _strains, trait = _vals,nperm=fd.nperm)
+
+ myCanvas = pid.PILCanvas(size=(400,300))
+ #plotBar(myCanvas,10,10,390,290,LRSArray,XLabel='LRS',YLabel='Frequency',title=' Histogram of Permutation Test',identification=fd.identification)
+ Plot.plotBar(myCanvas, LRSArray,XLabel='LRS',YLabel='Frequency',title=' Histogram of Permutation Test')
+ filename= webqtlUtil.genRandStr("Reg_")
+ myCanvas.save(webqtlConfig.IMGDIR+filename, format='gif')
+ img=HT.Image('/image/'+filename+'.gif',border=0,alt='Histogram of Permutation Test')
+
+ if fd.suggestive == None:
+ fd.suggestive = LRSArray[int(fd.nperm*0.37-1)]
+ else:
+ fd.suggestive = float(fd.suggestive)
+ if fd.significance == None:
+ fd.significance = LRSArray[int(fd.nperm*0.95-1)]
+ else:
+ fd.significance = float(fd.significance)
+
+ #########################################
+ # Permutation Graph
+ #########################################
+ permutationHeading = HT.Paragraph('Histogram of Permutation Test')
+ permutationHeading.__setattr__("class","title")
+ lrs = HT.Blockquote('Total of %d permutations' % fd.nperm,HT.P(),'Suggestive LRS = %2.2f' % LRSArray[int(fd.nperm*0.37-1)],\
+ HT.BR(),'Significant LRS = %2.2f' % LRSArray[int(fd.nperm*0.95-1)],HT.BR(),'Highly Significant LRS =%2.2f' % LRSArray[int(fd.nperm*0.99-1)])
+
+ permutation = HT.TableLite()
+ permutation.append(HT.TR(HT.TD(img)),HT.TR(HT.TD(lrs)))
+
+ _dispAllLRS = 0
+ if fd.formdata.getvalue('displayAllLRS'):
+ _dispAllLRS = 1
+ qtlresults2 = []
+ if _dispAllLRS:
+ filtered = qtlresults[:]
+ else:
+ filtered = filter(lambda x, y=fd.suggestive: x.lrs > y, qtlresults)
+ if len(filtered) == 0:
+ qtlresults2 = qtlresults[:]
+ qtlresults2.sort()
+ filtered = qtlresults2[-10:]
+
+ #########################################
+ # Marker regression report
+ #########################################
+ locusFormName = webqtlUtil.genRandStr("fm_")
+ locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \
+ enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden'))
+ hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':fd.RISet+"Geno",'CellID':'_', \
+ 'RISet':fd.RISet, 'incparentsf1':'on'}
+ for key in hddn.keys():
+ locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ regressionHeading = HT.Paragraph('Marker Regression Report')
+ regressionHeading.__setattr__("class","title")
+ if qtlresults2 != []:
+ report = HT.Blockquote(HT.Font('No association ',color="#FF0000"),HT.Font('with a likelihood ratio statistic greater than %3.1f was found. Here are the top 10 LRSs.' % fd.suggestive,color="#000000"))
+ else:
+ report = HT.Blockquote('The following loci in the %s data set have associations with the above trait data.\n' % fd.RISet, HT.P())
+ report.__setattr__("class","normalsize")
+
+ fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb')
+ textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn')
+
+ bottomInfo = HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),'LRS values marked with',HT.Font(' * ',color="red"), 'are greater than the significance threshold (specified by you or by permutation test). ' , HT.BR(), HT.BR(), HT.Strong('Additive Effect'), ' is half the difference in the mean phenotype of all cases that are homozygous for one parental allel at this marker minus the mean of all cases that are homozygous for the other parental allele at this marker. ','In the case of %s strains, for example,' % fd.RISet,' A positive additive effect indicates that %s alleles increase trait values. Negative additive effect indicates that %s alleles increase trait values.'% (fd.ppolar,fd.mpolar),Class="fs12 fwn")
+
+ c1 = HT.TD('LRS',Class="fs14 fwb ffl b1 cw cbrb")
+ c2 = HT.TD('Chr',Class="fs14 fwb ffl b1 cw cbrb")
+ c3 = HT.TD('Mb',Class="fs14 fwb ffl b1 cw cbrb")
+ c4 = HT.TD('Locus',Class="fs14 fwb ffl b1 cw cbrb")
+ c5 = HT.TD('Additive Effect',Class="fs14 fwb ffl b1 cw cbrb")
+
+ fpText.write('LRS\tChr\tMb\tLocus\tAdditive Effect\n')
+ hr = HT.TR(c1, c2, c3, c4, c5)
+ tbl = HT.TableLite(border=0, width="90%", cellpadding=0, cellspacing=0, Class="collap")
+ tbl.append(hr)
+ for ii in filtered:
+ #add by NL 06-22-2011: set LRS to 460 when LRS is infinite,
+ if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS:
+ LRS=webqtlConfig.MAXLRS #maximum LRS value
+ else:
+ LRS=ii.lrs
+ fpText.write('%2.3f\t%s\t%s\t%s\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive))
+ if LRS > fd.significance:
+ c1 = HT.TD('%3.3f*' % LRS, Class="fs13 b1 cbw cr")
+ else:
+ c1 = HT.TD('%3.3f' % LRS,Class="fs13 b1 cbw c222")
+ tbl.append(HT.TR(c1, HT.TD(ii.locus.chr,Class="fs13 b1 cbw c222"), HT.TD(ii.locus.Mb,Class="fs13 b1 cbw c222"), HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class="fs13 b1 cbw c222"), HT.TD('%3.3f' % ii.additive,Class="fs13 b1 cbw c222"),bgColor='#eeeeee'))
+
+ locusForm.append(tbl)
+ tbl2 = HT.TableLite(border=0, cellspacing=0, cellpadding=0,width="90%")
+ tbl2.append(HT.TR(HT.TD(bottomInfo)))
+ rv=HT.TD(permutationHeading,HT.Center(permutation),regressionHeading,report, HT.Center(locusForm,HT.P(),tbl2,HT.P()),width='55%',valign='top', bgColor='#eeeeee')
+ return rv
+
diff --git a/web/webqtl/markerRegression/MarkerRegressionPage.py b/web/webqtl/markerRegression/MarkerRegressionPage.py
new file mode 100755
index 00000000..7f830b4b
--- /dev/null
+++ b/web/webqtl/markerRegression/MarkerRegressionPage.py
@@ -0,0 +1,1626 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import time
+import string
+import math
+from math import *
+import piddle as pid
+import sys,os
+import httplib, urllib
+
+from htmlgen import HTMLgen2 as HT
+from utility import Plot
+from intervalAnalyst import GeneUtil
+from base.webqtlTrait import webqtlTrait
+from base.templatePage import templatePage
+from utility import webqtlUtil
+from base import webqtlConfig
+from dbFunction import webqtlDatabaseFunction
+from base.GeneralObject import GeneralObject
+
+import reaper
+import cPickle
+from utility.THCell import THCell
+from utility.TDCell import TDCell
+
+class MarkerRegressionPage(templatePage):
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ self.initializeParameters(fd)
+
+ filename= webqtlUtil.genRandStr("Itvl_")
+ ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrLengthMbList= self.getChrNameOrderIdLength(RISet=fd.RISet)
+
+ if self.mappingMethodId == '4': # For PLINK
+
+ traitInfoList = string.split(string.strip(fd.identification),':')
+ probesetName = string.strip(traitInfoList[-1])
+ plinkOutputFileName= webqtlUtil.genRandStr("%s_%s_"%(fd.RISet,probesetName))
+
+ # get related values from fd.allTraitData; the format of 'allTraitValueDict'is {strainName1: value=-0.2...}
+ fd.readData()
+ allTraitValueDict = fd.allTraitData
+
+ #automatically generate pheno txt file for PLINK
+ self.genPhenoTxtFileForPlink(phenoFileName=plinkOutputFileName,RISetName=fd.RISet,probesetName=probesetName, valueDict=allTraitValueDict)
+ # os.system full path is required for input and output files; specify missing value is -9999
+ plink_command = '%splink/plink --noweb --ped %splink/%s.ped --no-fid --no-parents --no-sex --no-pheno --map %splink/%s.map --pheno %s/%s.txt --pheno-name %s --missing-phenotype -9999 --out %s%s --assoc ' % (webqtlConfig.HTMLPATH, webqtlConfig.HTMLPATH, fd.RISet, webqtlConfig.HTMLPATH, fd.RISet, webqtlConfig.TMPDIR, plinkOutputFileName, probesetName, webqtlConfig.TMPDIR, plinkOutputFileName)
+
+ os.system(plink_command)
+
+ if fd.identification:
+ heading2 = HT.Paragraph('Trait ID: %s' % fd.identification)
+ heading2.__setattr__("class","subtitle")
+ self.dict['title'] = '%s: Genome Association' % fd.identification
+ else:
+ heading2 = ""
+ self.dict['title'] = 'Genome Association'
+
+ if fd.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 = ""
+
+ heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet)
+ heading.__setattr__("class","title")
+
+ # header info part:Trait Data Entered for HLC Set & Trait ID:
+ headerdiv = HT.TR(HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee'))
+
+ self.ChrList=ChrList # get chr name from '1' to 'X'
+ self.ChrLengthMbList = ChrLengthMbList
+
+ # build plink result dict based on chr, key is chr name, value is in list type including Snpname, bp and pvalue info
+ plinkResultDict={}
+ count,minPvalue,plinkResultDict =self.getPlinkResultDict(outputFileName=plinkOutputFileName,thresholdPvalue=self.pValue,ChrOrderIdNameDict=ChrOrderIdNameDict)
+
+ # if can not find results which are matched with assigned p-value, system info will show up
+ if count >0:
+
+ #for genome association report table
+ reportTable=""
+ # sortable table object
+ resultstable,tblobj,bottomInfo = self.GenReportForPLINK(ChrNameOrderIdDict=ChrNameOrderIdDict, RISet=fd.RISet,plinkResultDict=plinkResultDict,thresholdPvalue=self.pValue,chrList=self.ChrList)
+
+ # creat object for result table for sort function
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ sortby = ("Index", "up")
+ reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable")
+
+ descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0)
+ descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3)))
+ descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR())))
+ descriptionTable.append(bottomInfo)
+
+ # get each chr's length
+ self.ChrLengthMbList = map(lambda x: x/1000000.0, self.ChrLengthMbList) # change unit from bp to mb
+ self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0)# get total length of all chrs
+ if self.ChrLengthMbList:
+ self.GraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval
+ else:
+ self.GraphInterval = 1
+
+ # for human data, there's no CM value
+ self.ChrLengthCMList = []
+ self.ChrLengthCMSum = 0
+
+ # begin: common part with human data
+ intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight))
+ gifmap = self.plotIntMappingForPLINK(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, plinkResultDict=plinkResultDict)
+
+ intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png')
+ intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap')
+
+ TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200))
+ self.dict['body'] = str(headerdiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable)))
+
+ else:
+ heading = "Genome Association"
+ detail = ['There is no association with marker that meets this criteria. Please provide a less stringend threshold. The minimun p-value is %s.'%minPvalue]
+ self.error(heading=heading,detail=detail)
+ return
+
+ elif self.mappingMethodId == '1': # QTLreaper result
+ 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)
+
+ if fd.identification:
+ heading2 = HT.Paragraph('Trait ID: %s' % fd.identification)
+ heading2.__setattr__("class","subtitle")
+ self.dict['title'] = '%s: Genome Association' % fd.identification
+ else:
+ heading2 = ""
+ self.dict['title'] = 'Genome Association'
+
+ if fd.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 = "Genome Association"
+ detail = ['Fewer than %d strain data were entered for %s data set. No mapping attempted.' % (webqtlConfig.KMININFORMATIVE, fd.RISet)]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet)
+ heading.__setattr__("class","title")
+
+ datadiv = HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee')
+ resultstable,tblobj,bottomInfo = self.GenReport(ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars)
+ #resultstable = self.GenReport(fd, _genotype, _strains, _vals, _vars)
+
+ # creat object for result table for sort function
+ objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
+ cPickle.dump(tblobj, objfile)
+ objfile.close()
+
+ sortby = ("Index", "up")
+ reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable")
+
+ descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0)
+ descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3)))
+ descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR())))
+ descriptionTable.append(bottomInfo)
+
+ self.traitList=_vals
+
+ ##########################plot#######################
+
+ ################################################################
+ # Generate Chr list and Retrieve Length Information
+ ################################################################
+ self.genotype= _genotype
+ self.ChrList = [("All", -1)]
+
+ for i, indChr in enumerate(self.genotype):
+ self.ChrList.append((indChr.name, i))
+
+ self.cursor.execute("""
+ Select
+ Length from Chr_Length, InbredSet
+ where
+ Chr_Length.SpeciesId = InbredSet.SpeciesId AND
+ InbredSet.Name = '%s' AND
+ Chr_Length.Name in (%s)
+ Order by
+ OrderId
+ """ % (fd.RISet, string.join(map(lambda X: "'%s'" % X[0], self.ChrList[1:]), ", ")))
+
+ self.ChrLengthMbList = self.cursor.fetchall()
+ self.ChrLengthMbList = map(lambda x: x[0]/1000000.0, self.ChrLengthMbList)
+ self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0)
+ if self.ChrLengthMbList:
+ self.MbGraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval
+ else:
+ self.MbGraphInterval = 1
+
+ self.ChrLengthCMList = []
+ for i, _chr in enumerate(self.genotype):
+ self.ChrLengthCMList.append(_chr[-1].cM - _chr[0].cM)
+ self.ChrLengthCMSum = reduce(lambda x, y:x+y, self.ChrLengthCMList, 0.0)# used for calculate plot scale
+
+ self.GraphInterval = self.MbGraphInterval #Mb
+
+ # begin: common part with human data
+ intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight))
+ gifmap = self.plotIntMapping(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= "")
+ filename= webqtlUtil.genRandStr("Itvl_")
+ intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png')
+ intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap')
+
+ ################################################################
+ # footnote goes here
+ ################################################################
+ btminfo = HT.Paragraph(Id="smallsize") #Small('More information about this graph is available here.')
+
+ if (self.additiveChecked):
+ btminfo.append(HT.BR(), 'A positive additive coefficient (', HT.Font('green', color='green'), ' line) indicates that %s alleles increase trait values. In contrast, a negative additive coefficient (' % fd.ppolar, HT.Font('red', color='red'), ' line) indicates that %s alleles increase trait values.' % fd.mpolar)
+
+
+ TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200))
+
+ self.dict['body'] = str(datadiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable)))
+
+ # end: common part with human data
+
+ else:
+ pass
+
+
+ # add by NL 10-2-2011
+ def initializeParameters(self, fd):
+ """
+ Initializes all of the MarkerRegressionPage class parameters,
+ acquiring most values from the formdata (fd)
+ """
+ ###################################
+ # manhattam plot parameters
+ ###################################
+
+ self.graphHeight = 600
+ self.graphWidth = 1280
+ self.plotScale = 'physic'
+ self.selectedChr = -1
+ self.GRAPH_BACK_DARK_COLOR = pid.HexColor(0xF1F1F9)
+ self.GRAPH_BACK_LIGHT_COLOR = pid.HexColor(0xFBFBFF)
+ self.LRS_COLOR = pid.HexColor(0x0000FF)
+ self.LRS_LOD ='LRS'
+ self.lrsMax = float(fd.formdata.getvalue('lrsMax', 0))
+ self.startMb = fd.formdata.getvalue('startMb', "-1")
+ self.endMb = fd.formdata.getvalue('endMb', "-1")
+ self.mappingMethodId = fd.formdata.getvalue('mappingMethodId', "0")
+ self.permChecked=True
+ self.multipleInterval=False
+ self.SIGNIFICANT_WIDTH = 5
+ self.SUGGESTIVE_WIDTH = 5
+ self.SIGNIFICANT_COLOR = pid.HexColor(0xEBC7C7)
+ self.SUGGESTIVE_COLOR = pid.gainsboro
+ self.colorCollection = [self.LRS_COLOR]
+ self.additiveChecked= True
+ self.ADDITIVE_COLOR_POSITIVE = pid.green
+ self.legendChecked =False
+ self.pValue=float(fd.formdata.getvalue('pValue',-1))
+
+ # allow user to input p-value greater than 1,
+ # in this case, the value will be treated as -lgP value. so the input value needs to be transferred to power of 10 format
+ if self.pValue >1:
+ self.pValue =10**-(self.pValue)
+
+ try:
+ self.startMb = float(self.startMb)
+ self.endMb = float(self.endMb)
+ if self.startMb > self.endMb:
+ temp = self.startMb
+ self.startMb = self.endMb
+ self.endMb = temp
+ #minimal distance 10bp
+ if self.endMb - self.startMb < 0.00001:
+ self.endMb = self.startMb + 0.00001
+ except:
+ self.startMb = self.endMb = -1
+
+ def GenReportForPLINK(self, ChrNameOrderIdDict={},RISet='',plinkResultDict= {},thresholdPvalue=-1,chrList=[]):
+
+ 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.'
+ #########################################
+ # Genome Association report
+ #########################################
+ locusFormName = webqtlUtil.genRandStr("fm_")
+ locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \
+ enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden'))
+ hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':RISet+"Geno",'CellID':'_', \
+ 'RISet':RISet, 'incparentsf1':'on'}
+ for key in hddn.keys():
+ locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ regressionHeading = HT.Paragraph('Genome Association Report')
+ regressionHeading.__setattr__("class","title")
+
+ filename= webqtlUtil.genRandStr("GenomeAsscociation_")
+ fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb')
+ fpText.write('The loci meet the criteria of P-Value <= %3.6f.\n'%thresholdPvalue)
+ pValueInfo =HT.Paragraph('The loci meet the criteria of P-Value <= %3.6f.\n'%thresholdPvalue)
+
+ textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn')
+ bottomInfo = HT.TR(HT.TD(HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),Class="fs12 fwn"), colspan=3))
+
+ tblobj={} # build dict for genTableObj function; keys include header and body
+ tblobj_header = [] # value of key 'header'
+ tblobj_body=[] # value of key 'body'
+ reportHeaderRow=[] # header row list for tblobj_header (html part)
+ headerList=['Index','SNP Name','Chr','Mb','-log(P)']
+ headerStyle="fs14 fwb ffl b1 cw cbrb" # style of the header
+ cellColorStyle = "fs13 b1 fwn c222" # style of the cells
+
+ if headerList:
+ for ncol, item in enumerate(headerList):
+ reportHeaderRow.append(THCell(HT.TD(item, Class=headerStyle, valign='bottom',nowrap='ON'),text=item, idx=ncol))
+ #download file for table headers' names
+ fpText.write('SNP_Name\tChromosome\tMb\t-log(P)\n')
+
+ tblobj_header.append(reportHeaderRow)
+ tblobj['header']=tblobj_header
+
+ index=1
+ for chr in chrList:
+
+ if plinkResultDict.has_key(chr):
+ if chr in ChrNameOrderIdDict.keys():
+ chrOrderId =ChrNameOrderIdDict[chr]
+ else:
+ chrOrderId=chr
+
+ valueList=plinkResultDict[chr]
+
+ for value in valueList:
+ reportBodyRow=[] # row list for tblobj_body (html part)
+ snpName=value[0]
+ bp=value[1]
+ mb=int(bp)/1000000.0
+
+ try:
+ pValue =float(value[2])
+ except:
+ pValue =1
+ formattedPvalue = -math.log10(pValue)
+
+ formattedPvalue = webqtlUtil.SciFloat(formattedPvalue)
+ dbSnprs=snpName.replace('rs','')
+ SnpHref = HT.Href(text=snpName, url="http://www.ncbi.nlm.nih.gov/projects/SNP/snp_ref.cgi?rs=%s"%dbSnprs, target="_blank")
+
+ selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)")
+ reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index))
+ reportBodyRow.append(TDCell(HT.TD(SnpHref, Class=cellColorStyle,nowrap='ON'),snpName, snpName))
+ reportBodyRow.append(TDCell(HT.TD(chr, Class=cellColorStyle, align="center",nowrap='ON'),chr, chrOrderId))
+ reportBodyRow.append(TDCell(HT.TD('%3.6f'%mb, Class=cellColorStyle, align="center",nowrap='ON'),mb, mb))
+ reportBodyRow.append(TDCell(HT.TD(formattedPvalue, Class=cellColorStyle, align="center",nowrap='ON'),formattedPvalue, float(formattedPvalue)))
+
+ fpText.write('%s\t%s\t%3.6f\t%s\n' % (snpName, str(chr), mb, formattedPvalue))
+ index+=1
+
+ tblobj_body.append(reportBodyRow)
+
+ tblobj['body']=tblobj_body
+ rv=HT.TR(HT.TD(regressionHeading,pValueInfo, locusForm, HT.P(), width='55%',valign='top', align='left',bgColor='#eeeeee'))
+
+ return rv, tblobj,bottomInfo
+
+
+ def GenReport(self, ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars= []):
+ 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.'
+ #calculate QTL for each trait
+ self.qtlresults = []
+ if webqtlUtil.ListNotNull(_vars):
+ qtlresults = _genotype.regression(strains = _strains, trait = _vals, variance = _vars)
+ LRSArray = _genotype.permutation(strains = _strains, trait = _vals, variance = _vars, nperm=fd.nperm)
+ else:
+ qtlresults = _genotype.regression(strains = _strains, trait = _vals)
+ LRSArray = _genotype.permutation(strains = _strains, trait = _vals,nperm=fd.nperm)
+
+ self.qtlresults.append(qtlresults)
+
+ filename= webqtlUtil.genRandStr("GenomeAsscociation_")
+
+ # set suggestive, significant and highly significant LRS
+ if fd.suggestive == None:
+ fd.suggestive = LRSArray[int(fd.nperm*0.37-1)]
+ else:
+ fd.suggestive = float(fd.suggestive)
+ if fd.significance == None:
+ fd.significance = LRSArray[int(fd.nperm*0.95-1)]
+ else:
+ fd.significance = float(fd.significance)
+
+ self.significance =fd.significance
+ self.suggestive = fd.suggestive
+ self.highlysignificant = LRSArray[int(fd.nperm*0.99-1)]
+ _dispAllLRS = 0
+ if fd.formdata.getvalue('displayAllLRS'):
+ _dispAllLRS = 1
+ qtlresults2 = []
+ if _dispAllLRS:
+ filtered = qtlresults[:]
+ else:
+ filtered = filter(lambda x, y=fd.suggestive: x.lrs > y, qtlresults)
+ if len(filtered) == 0:
+ qtlresults2 = qtlresults[:]
+ qtlresults2.sort()
+ filtered = qtlresults2[-10:]
+
+
+
+ #########################################
+ # Genome Association report
+ #########################################
+ locusFormName = webqtlUtil.genRandStr("fm_")
+ locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \
+ enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden'))
+ hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':fd.RISet+"Geno",'CellID':'_', \
+ 'RISet':fd.RISet, 'incparentsf1':'on'}
+ for key in hddn.keys():
+ locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+
+ regressionHeading = HT.Paragraph('Genome Association Report')
+ regressionHeading.__setattr__("class","title")
+ # report is the info part above report table
+ if qtlresults2 != []:
+ report = HT.Blockquote(HT.Font('No association ',color="#FF0000"),HT.Font('with a likelihood ratio statistic greater than %3.1f was found. Here are the top 10 LRSs.' % fd.suggestive,color="#000000"))
+ else:
+ report = HT.Blockquote('The following loci in the %s data set have associations with the above trait data.\n' % fd.RISet, HT.P())
+ report.__setattr__("class","normalsize")
+
+ fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb')
+ fpText.write('Suggestive LRS =%3.2f\n'%self.suggestive)
+ fpText.write('Significant LRS =%3.2f\n'%self.significance)
+ fpText.write('Highly Significant LRS =%3.2f\n'%self.highlysignificant)
+ LRSInfo =HT.Paragraph(' Suggestive LRS =%3.2f\n'%fd.suggestive, HT.BR(), ' Significant LRS =%3.2f\n'%fd.significance,HT.BR(),' Highly Significant LRS =%3.2f\n' % self.highlysignificant)
+
+ textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn')
+
+ bottomInfo = HT.TR(HT.TD(HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),'LRS values marked with',HT.Font(' * ',color="red"), 'are greater than the significance threshold (specified by you or by permutation test). ' , HT.BR(), HT.BR(), HT.Strong('Additive Effect'), ' is half the difference in the mean phenotype of all cases that are homozygous for one parental allel at this marker minus the mean of all cases that are homozygous for the other parental allele at this marker. ','In the case of %s strains, for example,' % fd.RISet,' A positive additive effect indicates that %s alleles increase trait values. Negative additive effect indicates that %s alleles increase trait values.'% (fd.ppolar,fd.mpolar),Class="fs12 fwn")))
+
+ tblobj={} # build dict for genTableObj function; keys include header and body
+ tblobj_header = [] # value of key 'header'
+ tblobj_body=[] # value of key 'body'
+ reportHeaderRow=[] # header row list for tblobj_header (html part)
+ headerStyle="fs14 fwb ffl b1 cw cbrb" # style of the header
+ cellColorStyle = "fs13 b1 fwn c222" # style of the cells
+
+ headerList=['Index','LRS','Chr','Mb','Locus','Additive Effect']
+ for ncol, item in enumerate(headerList):
+ reportHeaderRow.append(THCell(HT.TD(item, Class=headerStyle, valign='bottom',nowrap='ON'),text=item, idx=ncol))
+
+ if fd.genotype.type == 'intercross':
+ ncol =len(headerList)
+ reportHeaderRow.append(THCell(HT.TD('Dominance Effect', Class=headerStyle, valign='bottom',nowrap='ON'),text='Dominance Effect', idx=ncol))
+
+ #download file for table headers' names
+ fpText.write('LRS\tChromosome\tMb\tLocus\tAdditive Effect\tDominance Effect\n')
+
+ index=1
+ for ii in filtered:
+ #add by NL 06-20-2011: set LRS to 460 when LRS is infinite,
+ if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS:
+ LRS=webqtlConfig.MAXLRS #maximum LRS value
+ else:
+ LRS=ii.lrs
+
+ if LRS > fd.significance:
+ lrs = HT.TD(HT.Font('%3.3f*' % LRS, color='#FF0000'),Class=cellColorStyle)
+ else:
+ lrs = HT.TD('%3.3f' % LRS,Class=cellColorStyle)
+
+ if ii.locus.chr in ChrNameOrderIdDict.keys():
+ chrOrderId =ChrNameOrderIdDict[ii.locus.chr]
+ else:
+ chrOrderId=ii.locus.chr
+
+ reportBodyRow=[] # row list for tblobj_body (html part)
+ selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)")
+ reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index))
+ reportBodyRow.append(TDCell(lrs,LRS, LRS))
+ reportBodyRow.append(TDCell(HT.TD(ii.locus.chr, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.chr, chrOrderId))
+ reportBodyRow.append(TDCell(HT.TD('%3.6f'%ii.locus.Mb, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.Mb, ii.locus.Mb))
+ reportBodyRow.append(TDCell(HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.name, ii.locus.name))
+ reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.additive, Class=cellColorStyle, align="center",nowrap='ON'),ii.additive, ii.additive))
+ reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.dominance, Class=cellColorStyle, align="center",nowrap='ON'),ii.dominance, ii.dominance))
+
+ fpText.write('%2.3f\t%s\t%3.6f\t%s\t%2.3f\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive, ii.dominance))
+ index+=1
+ tblobj_body.append(reportBodyRow)
+ else:
+ #download file for table headers' names
+ fpText.write('LRS\tChromosome\tMb\tLocus\tAdditive Effect\n')
+
+ index=1
+ for ii in filtered:
+ #add by NL 06-20-2011: set LRS to 460 when LRS is infinite,
+ if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS:
+ LRS=webqtlConfig.MAXLRS #maximum LRS value
+ else:
+ LRS=ii.lrs
+
+ if LRS > fd.significance:
+ lrs = HT.TD(HT.Font('%3.3f*' % LRS, color='#FF0000'),Class=cellColorStyle)
+ else:
+ lrs = HT.TD('%3.3f' % LRS,Class=cellColorStyle)
+
+ if ii.locus.chr in ChrNameOrderIdDict.keys():
+ chrOrderId =ChrNameOrderIdDict[ii.locus.chr]
+ else:
+ chrOrderId=ii.locus.chr
+
+ reportBodyRow=[] # row list for tblobj_body (html part)
+ selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)")
+ reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index))
+ reportBodyRow.append(TDCell(lrs,LRS, LRS))
+ reportBodyRow.append(TDCell(HT.TD(ii.locus.chr, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.chr, chrOrderId))
+ reportBodyRow.append(TDCell(HT.TD('%3.6f'%ii.locus.Mb, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.Mb, ii.locus.Mb))
+ reportBodyRow.append(TDCell(HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.name, ii.locus.name))
+ reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.additive, Class=cellColorStyle, align="center",nowrap='ON'),ii.additive, ii.additive))
+
+ fpText.write('%2.3f\t%s\t%3.6f\t%s\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive))
+ index+=1
+ tblobj_body.append(reportBodyRow)
+
+ tblobj_header.append(reportHeaderRow)
+ tblobj['header']=tblobj_header
+ tblobj['body']=tblobj_body
+
+ rv=HT.TD(regressionHeading,LRSInfo,report, locusForm, HT.P(),width='55%',valign='top', align='left', bgColor='#eeeeee')
+ if fd.genotype.type == 'intercross':
+ bottomInfo.append(HT.BR(), HT.BR(), HT.Strong('Dominance Effect'),' is the difference between the mean trait value of cases heterozygous at a marker and the average mean for the two groups homozygous at this marker: e.g., BD - (BB+DD)/2]. A positive dominance effect indicates that the average phenotype of BD heterozygotes exceeds the mean of BB and DD homozygotes. No dominance deviation can be computed for a set of recombinant inbred strains or for a backcross.')
+ return rv,tblobj,bottomInfo
+
+ return rv,tblobj,bottomInfo
+
+ def plotIntMappingForPLINK(self, fd, canvas, offset= (80, 120, 20, 80), zoom = 1, startMb = None, endMb = None, showLocusForm = "",plinkResultDict={}):
+ #calculating margins
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ xLeftOffset = int(xLeftOffset*fontZoom)
+ xRightOffset = int(xRightOffset*fontZoom)
+ yBottomOffset = int(yBottomOffset*fontZoom)
+
+ cWidth = canvas.size[0]
+ cHeight = canvas.size[1]
+ plotWidth = cWidth - xLeftOffset - xRightOffset
+ plotHeight = cHeight - yTopOffset - yBottomOffset
+ startPixelX = xLeftOffset
+ endPixelX = (xLeftOffset + plotWidth)
+
+ #Drawing Area Height
+ drawAreaHeight = plotHeight
+ if self.plotScale == 'physic' and self.selectedChr > -1: # for single chr
+ drawAreaHeight -= self.ENSEMBL_BAND_HEIGHT + self.UCSC_BAND_HEIGHT+ self.WEBQTL_BAND_HEIGHT + 3*self.BAND_SPACING+ 10*zoom
+ if self.geneChecked:
+ drawAreaHeight -= self.NUM_GENE_ROWS*self.EACH_GENE_HEIGHT + 3*self.BAND_SPACING + 10*zoom
+ else:
+ if self.selectedChr > -1:
+ drawAreaHeight -= 20
+ else:# for all chrs
+ drawAreaHeight -= 30
+
+ #Image map
+ gifmap = HT.Map(name='WebQTLImageMap')
+
+ newoffset = (xLeftOffset, xRightOffset, yTopOffset, yBottomOffset)
+ # Draw the alternating-color background first and get plotXScale
+ plotXScale = self.drawGraphBackgroundForPLINK(canvas, gifmap, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb,plinkResultDict=plinkResultDict)
+
+ # Draw X axis
+ self.drawXAxisForPLINK(fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb)
+ # Draw manhattam plot
+ self.drawManhattanPlotForPLINK(canvas, drawAreaHeight, gifmap, plotXScale, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb,plinkResultDict=plinkResultDict,thresholdPvalue=self.pValue)
+
+ return gifmap
+
+
+ def plotIntMapping(self, fd, canvas, offset= (80, 120, 20, 80), zoom = 1, startMb = None, endMb = None, showLocusForm = ""):
+ #calculating margins
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ xLeftOffset = int(xLeftOffset*fontZoom)
+ xRightOffset = int(xRightOffset*fontZoom)
+ yBottomOffset = int(yBottomOffset*fontZoom)
+
+ cWidth = canvas.size[0]
+ cHeight = canvas.size[1]
+ plotWidth = cWidth - xLeftOffset - xRightOffset
+ plotHeight = cHeight - yTopOffset - yBottomOffset
+ startPixelX = xLeftOffset
+ endPixelX = (xLeftOffset + plotWidth)
+
+ #Drawing Area Height
+ drawAreaHeight = plotHeight
+ if self.plotScale == 'physic' and self.selectedChr > -1: # for single chr
+ drawAreaHeight -= self.ENSEMBL_BAND_HEIGHT + self.UCSC_BAND_HEIGHT+ self.WEBQTL_BAND_HEIGHT + 3*self.BAND_SPACING+ 10*zoom
+ if self.geneChecked:
+ drawAreaHeight -= self.NUM_GENE_ROWS*self.EACH_GENE_HEIGHT + 3*self.BAND_SPACING + 10*zoom
+ else:# for all chrs
+ if self.selectedChr > -1:
+ drawAreaHeight -= 20
+ else:
+ drawAreaHeight -= 30
+
+ #Image map
+ gifmap = HT.Map(name='WebQTLImageMap')
+
+ newoffset = (xLeftOffset, xRightOffset, yTopOffset, yBottomOffset)
+ # Draw the alternating-color background first and get plotXScale
+ plotXScale = self.drawGraphBackground(canvas, gifmap, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb)
+
+ # Draw X axis
+ self.drawXAxis(fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb)
+ # Draw QTL curve
+ self.drawQTL(canvas, drawAreaHeight, gifmap, plotXScale, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb)
+
+ #draw legend
+ if self.multipleInterval:
+ self.drawMultiTraitName(fd, canvas, gifmap, showLocusForm, offset=newoffset)
+ elif self.legendChecked:
+ self.drawLegendPanel(fd, canvas, offset=newoffset)
+ else:
+ pass
+
+ #draw position, no need to use a separate function
+ if fd.genotype.Mbmap:
+ self.drawProbeSetPosition(canvas, plotXScale, offset=newoffset)
+
+ return gifmap
+
+
+ # functions for manhattam plot of markers
+ def drawManhattanPlotForPLINK(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None,plinkResultDict={},thresholdPvalue=-1):
+
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ # INTERCROSS = (self.genotype.type=="intercross")
+ INTERCROSS ='' #??????
+
+ ChrLengthDistList = self.ChrLengthMbList
+ drawRegionDistance = self.ChrLengthMbSum
+ GraphInterval=self.GraphInterval
+ pvalueHeightThresh = drawAreaHeight - 80 #ZS: Otherwise the plot gets very close to the chromosome labels
+
+ #draw the pvalue scale
+ #We first determine whether or not we are using a sliding scale.
+ #If so, we need to compute the maximum pvalue value to determine where the max y-value should be, and call this pvalueMax.
+ #pvalueTop is then defined to be above the pvalueMax by enough to add one additional pvalueScale increment.
+ #if we are using a set-scale, then we set pvalueTop to be the user's value, and pvalueMax doesn't matter.
+
+ # for human data we use p value instead of lrs
+ pValueList=[]
+ for key in plinkResultDict:
+ valueList = plinkResultDict[key]
+ for item in valueList:
+ pValue = item[-1]
+ pValueList.append(pValue)
+
+ formattedPValueList=[]
+ for pValue in pValueList:
+ try:
+ pValue=float(pValue)
+ except:
+ pValue =1
+ formattedpValue = -math.log10(pValue)
+ formattedPValueList.append(formattedpValue)
+
+ #sliding scale
+ pvalueMax = max(formattedPValueList)
+ #pvalueMax =pvalueMax +1
+ # no permutation result for plink func: GenReport()
+ pvalueMin = int(-math.log10(thresholdPvalue))
+
+ if pvalueMax> 100:
+ pvalueScale = 20.0
+ elif pvalueMax > 20:
+ pvalueScale = 5.0
+ elif pvalueMax > 7.5:
+ pvalueScale = 2.5
+ else:
+ pvalueScale = 1.0
+
+ # the base line for x-axis is -log(thresholdPvalue)
+ pvalueAxisList = Plot.frange(pvalueMin, pvalueMax, pvalueScale)
+ #make sure the user's value appears on the y-axis
+ #ZS: There is no way to do this without making the position of the points not directly proportional to a given distance on the y-axis
+ #tempPvalueMax=round(pvalueMax)
+ tempPvalueMax = pvalueAxisList[len(pvalueAxisList)-1] + pvalueScale
+ pvalueAxisList.append(tempPvalueMax)
+
+ #ZS: I don't understand this; the if statement will be true for any number that isn't exactly X.5.
+ #if abs(tempPvalueMax-pvalueMax) <0.5:
+ # tempPvalueMax=tempPvalueMax+1
+ # pvalueAxisList.append(tempPvalueMax)
+
+ #draw the "pvalue" string to the left of the axis
+ pvalueScaleFont=pid.Font(ttf="verdana", size=14*fontZoom, bold=0)
+ pvalueLODFont=pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0)
+ yZero = yTopOffset + plotHeight
+
+ #yAxis label display area
+ yAxis_label ='-log(P)'
+ canvas.drawString(yAxis_label, xLeftOffset - canvas.stringWidth("999.99", font=pvalueScaleFont) - 10*zoom, \
+ yZero - 150, font=pvalueLODFont, color=pid.black, angle=90)
+
+ for i,item in enumerate(pvalueAxisList):
+ ypvalue = yZero - (float(i)/float(len(pvalueAxisList) - 1)) * pvalueHeightThresh
+ canvas.drawLine(xLeftOffset, ypvalue, xLeftOffset - 4, ypvalue, color=self.LRS_COLOR, width=1*zoom)
+ scaleStr = "%2.1f" % item
+ #added by NL 6-24-2011:Y-axis scale display
+ canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=pvalueScaleFont)-5, ypvalue+3, font=pvalueScaleFont, color=self.LRS_COLOR)
+
+ ChrList=self.ChrList
+ startPosX = xLeftOffset
+
+ for i, chr in enumerate(ChrList):
+
+ if plinkResultDict.has_key(chr):
+ plinkresultList = plinkResultDict[chr]
+
+ m = 0
+ #add by NL 06-24-2011: for mahanttam plot
+ symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0)
+ # color for point in each chr
+ chrCount=len(ChrList)
+ chrColorDict =self.getColorForMarker(chrCount=chrCount,flag=1)
+ for j, item in enumerate(plinkresultList):
+ try :
+ mb=float(item[1])/1000000.0
+ except:
+ mb=0
+
+ try :
+ pvalue =float(item[-1])
+ except:
+ pvalue =1
+
+ try:
+ snpName = item[0]
+ except:
+ snpName=''
+
+ formattedPvalue = -math.log10(pvalue)
+
+ Xc = startPosX + (mb-startMb)*plotXScale
+ Yc = yZero - (formattedPvalue-pvalueMin)*pvalueHeightThresh/(tempPvalueMax - pvalueMin)
+ canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=chrColorDict[i], font=symbolFont)
+ m += 1
+
+ startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale
+
+ canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset, color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis
+
+ def drawQTL(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None):
+
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ INTERCROSS = (self.genotype.type=="intercross")
+
+ ChrLengthDistList = self.ChrLengthMbList
+ GraphInterval=self.GraphInterval
+ LRSHeightThresh = drawAreaHeight
+ AdditiveHeightThresh = drawAreaHeight/2
+ DominanceHeightThresh = drawAreaHeight/2
+
+ #draw the LRS scale
+ #We first determine whether or not we are using a sliding scale.
+ #If so, we need to compute the maximum LRS value to determine where the max y-value should be, and call this LRSMax.
+ #LRSTop is then defined to be above the LRSMax by enough to add one additional LRSScale increment.
+ #if we are using a set-scale, then we set LRSTop to be the user's value, and LRSMax doesn't matter.
+
+ if self.LRS_LOD == 'LOD':
+ lodm = self.LODFACTOR
+ else:
+ lodm = 1.0
+
+ if self.lrsMax <= 0: #sliding scale
+ LRSMax = max(map(max, self.qtlresults)).lrs
+ #genotype trait will give infinite LRS
+ LRSMax = min(LRSMax, webqtlConfig.MAXLRS)
+ LRSMax = max(self.significance, LRSMax)
+ else:
+ LRSMax = self.lrsMax*lodm
+
+ if LRSMax/lodm > 100:
+ LRSScale = 20.0
+ elif LRSMax/lodm > 20:
+ LRSScale = 5.0
+ elif LRSMax/lodm > 7.5:
+ LRSScale = 2.5
+ else:
+ LRSScale = 1.0
+
+ LRSAxisList = Plot.frange(LRSScale, LRSMax/lodm, LRSScale)
+ #make sure the user's value appears on the y-axis
+ #update by NL 6-21-2011: round the LOD value to 100 when LRSMax is equal to 460
+ LRSAxisList.append(round(LRSMax/lodm))
+
+ #draw the "LRS" or "LOD" string to the left of the axis
+ LRSScaleFont=pid.Font(ttf="verdana", size=14*fontZoom, bold=0)
+ LRSLODFont=pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0)
+ yZero = yTopOffset + plotHeight
+
+ #yAxis label display area
+ canvas.drawString(self.LRS_LOD, xLeftOffset - canvas.stringWidth("999.99", font=LRSScaleFont) - 10*zoom, \
+ yZero - 150, font=LRSLODFont, color=pid.black, angle=90)
+
+ for item in LRSAxisList:
+ yLRS = yZero - (item*lodm/LRSMax) * LRSHeightThresh
+ canvas.drawLine(xLeftOffset, yLRS, xLeftOffset - 4, yLRS, color=self.LRS_COLOR, width=1*zoom)
+ scaleStr = "%2.1f" % item
+ #added by NL 6-24-2011:Y-axis scale display
+ canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=LRSScaleFont)-5, yLRS+3, font=LRSScaleFont, color=self.LRS_COLOR)
+
+
+ #"Significant" and "Suggestive" Drawing Routine
+ # ======= Draw the thick lines for "Significant" and "Suggestive" ===== (crowell: I tried to make the SNPs draw over these lines, but piddle wouldn't have it...)
+ if self.permChecked and not self.multipleInterval:
+ significantY = yZero - self.significance*LRSHeightThresh/LRSMax
+ suggestiveY = yZero - self.suggestive*LRSHeightThresh/LRSMax
+
+
+ startPosX = xLeftOffset
+ for i, _chr in enumerate(self.genotype):
+ rightEdge = int(startPosX + self.ChrLengthDistList[i]*plotXScale - self.SUGGESTIVE_WIDTH/1.5)
+ #added by NL 6-24-2011:draw suggestive line (grey one)
+ canvas.drawLine(startPosX+self.SUGGESTIVE_WIDTH/1.5, suggestiveY, rightEdge, suggestiveY, color=self.SUGGESTIVE_COLOR,
+ width=self.SUGGESTIVE_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2))
+ #added by NL 6-24-2011:draw significant line (pink one)
+ canvas.drawLine(startPosX+self.SUGGESTIVE_WIDTH/1.5, significantY, rightEdge, significantY, color=self.SIGNIFICANT_COLOR,
+ width=self.SIGNIFICANT_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2))
+ sugg_coords = "%d, %d, %d, %d" % (startPosX, suggestiveY-2, rightEdge + 2*zoom, suggestiveY+2)
+ sig_coords = "%d, %d, %d, %d" % (startPosX, significantY-2, rightEdge + 2*zoom, significantY+2)
+ if self.LRS_LOD == 'LRS':
+ sugg_title = "Suggestive LRS = %0.2f" % self.suggestive
+ sig_title = "Significant LRS = %0.2f" % self.significance
+ else:
+ sugg_title = "Suggestive LOD = %0.2f" % (self.suggestive/4.61)
+ sig_title = "Significant LOD = %0.2f" % (self.significance/4.61)
+ Areas1 = HT.Area(shape='rect',coords=sugg_coords,title=sugg_title)
+ Areas2 = HT.Area(shape='rect',coords=sig_coords,title=sig_title)
+ gifmap.areas.append(Areas1)
+ gifmap.areas.append(Areas2)
+
+ startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale
+
+
+ if self.multipleInterval:
+ lrsEdgeWidth = 1
+ else:
+ additiveMax = max(map(lambda X : abs(X.additive), self.qtlresults[0]))
+ if INTERCROSS:
+ dominanceMax = max(map(lambda X : abs(X.dominance), self.qtlresults[0]))
+ else:
+ dominanceMax = -1
+ lrsEdgeWidth = 2
+ for i, qtlresult in enumerate(self.qtlresults):
+ m = 0
+ startPosX = xLeftOffset
+ thisLRSColor = self.colorCollection[i]
+
+ #add by NL 06-24-2011: for mahanttam plot
+ symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0)
+
+ for j, _chr in enumerate(self.genotype):
+ chrCount=len(self.genotype)
+ chrColorDict =self.getColorForMarker(chrCount=chrCount,flag=1)
+ LRSCoordXY = []
+ AdditiveCoordXY = []
+ DominanceCoordXY = []
+ for k, _locus in enumerate(_chr):
+ if self.plotScale == 'physic':
+ Xc = startPosX + (_locus.Mb-startMb)*plotXScale
+ else:
+ Xc = startPosX + (_locus.cM-_chr[0].cM)*plotXScale
+ # updated by NL 06-18-2011:
+ # fix the over limit LRS graph issue since genotype trait may give infinite LRS;
+ # for any lrs is over than 460(LRS max in this system), it will be reset to 460
+ if qtlresult[m].lrs> 460 or qtlresult[m].lrs=='inf':
+ Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSMax
+ else:
+ Yc = yZero - qtlresult[m].lrs*LRSHeightThresh/LRSMax
+
+ LRSCoordXY.append((Xc, Yc))
+ #add by NL 06-24-2011: for mahanttam plot
+ #self.significance/4.61 consider chr and LOD
+ # significantY = yZero - self.significance*LRSHeightThresh/LRSMax
+ # if Yc >significantY:
+ # canvas.drawString(":", Xc-canvas.stringWidth(":",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont)
+ # else:
+ # canvas.drawString(":", Xc-canvas.stringWidth(":",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont)
+
+ # add by NL 06-27-2011: eliminate imputed value when locus name is equal to '-'
+ if (qtlresult[m].locus.name) and (qtlresult[m].locus.name!=' - '):
+ canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=chrColorDict[j], font=symbolFont)
+
+ if not self.multipleInterval and self.additiveChecked:
+ Yc = yZero - qtlresult[m].additive*AdditiveHeightThresh/additiveMax
+ AdditiveCoordXY.append((Xc, Yc))
+ if not self.multipleInterval and INTERCROSS and self.additiveChecked:
+ Yc = yZero - qtlresult[m].dominance*DominanceHeightThresh/dominanceMax
+ DominanceCoordXY.append((Xc, Yc))
+ m += 1
+
+ startPosX += (ChrLengthDistList[j]+GraphInterval)*plotXScale
+
+
+ ###draw additive scale
+ if not self.multipleInterval and self.additiveChecked:
+ additiveScaleFont=pid.Font(ttf="verdana",size=12*fontZoom,bold=0)
+ additiveScale = Plot.detScaleOld(0,additiveMax)
+ additiveStep = (additiveScale[1]-additiveScale[0])/additiveScale[2]
+ additiveAxisList = Plot.frange(0, additiveScale[1], additiveStep)
+ maxAdd = additiveScale[1]
+ addPlotScale = AdditiveHeightThresh/additiveMax
+
+ additiveAxisList.append(additiveScale[1])
+ for item in additiveAxisList:
+ additiveY = yZero - item*addPlotScale
+ canvas.drawLine(xLeftOffset + plotWidth,additiveY,xLeftOffset+4+ plotWidth,additiveY,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom)
+ scaleStr = "%2.3f" % item
+ canvas.drawString(scaleStr,xLeftOffset + plotWidth +6,additiveY+5,font=additiveScaleFont,color=self.ADDITIVE_COLOR_POSITIVE)
+
+ canvas.drawLine(xLeftOffset+plotWidth,additiveY,xLeftOffset+plotWidth,yZero,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom)
+
+ canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset, color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis
+
+ def drawGraphBackgroundForPLINK(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None,plinkResultDict={} ):
+
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ #calculate plot scale
+ #XZ: all of these global variables should be passed from function signiture
+ ChrLengthDistList = self.ChrLengthMbList
+ drawRegionDistance = self.ChrLengthMbSum
+ GraphInterval=self.GraphInterval
+ ChrList =self.ChrList
+
+ #multiple chromosome view
+ plotXScale = plotWidth / ((len(ChrList)-1)*GraphInterval + drawRegionDistance)
+
+ startPosX = xLeftOffset
+ chrLabelFont=pid.Font(ttf="verdana",size=24*fontZoom,bold=0)
+
+ for i, _chr in enumerate(ChrList):
+
+ if (i % 2 == 0):
+ theBackColor = self.GRAPH_BACK_DARK_COLOR
+ else:
+ theBackColor = self.GRAPH_BACK_LIGHT_COLOR
+ # NL:resize chr width for drawing
+ if float(ChrLengthDistList[i])<90:
+ ChrLengthDistList[i]=90
+ #draw the shaded boxes and the sig/sug thick lines
+ canvas.drawRect(startPosX, yTopOffset, startPosX + ChrLengthDistList[i]*plotXScale, \
+ yTopOffset+plotHeight, edgeColor=pid.gainsboro,fillColor=theBackColor)
+
+ chrNameWidth = canvas.stringWidth(_chr, font=chrLabelFont)
+ chrStartPix = startPosX + (ChrLengthDistList[i]*plotXScale -chrNameWidth)/2
+ chrEndPix = startPosX + (ChrLengthDistList[i]*plotXScale +chrNameWidth)/2
+
+ canvas.drawString(_chr, chrStartPix, yTopOffset +20,font = chrLabelFont,color=pid.dimgray)
+ COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20)
+
+ #add by NL 09-03-2010
+ HREF = "javascript:changeView(%d,%s);" % (i,ChrLengthDistList)
+ Areas = HT.Area(shape='rect',coords=COORDS,href=HREF)
+ gifmap.areas.append(Areas)
+ startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale
+
+ return plotXScale
+
+
+ def drawGraphBackground(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None):
+ ##conditions
+ ##multiple Chromosome view
+ ##single Chromosome Physical
+ ##single Chromosome Genetic
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ #calculate plot scale
+ if self.plotScale != 'physic':
+ self.ChrLengthDistList = self.ChrLengthCMList
+ drawRegionDistance = self.ChrLengthCMSum
+ else:
+ self.ChrLengthDistList = self.ChrLengthMbList
+ drawRegionDistance = self.ChrLengthMbSum
+
+ if self.selectedChr > -1: #single chromosome view
+ spacingAmt = plotWidth/13.5
+ i = 0
+ for startPix in Plot.frange(xLeftOffset, xLeftOffset+plotWidth, spacingAmt):
+ if (i % 2 == 0):
+ theBackColor = self.GRAPH_BACK_DARK_COLOR
+ else:
+ theBackColor = self.GRAPH_BACK_LIGHT_COLOR
+ i += 1
+ canvas.drawRect(startPix, yTopOffset, min(startPix+spacingAmt, xLeftOffset+plotWidth), \
+ yTopOffset+plotHeight, edgeColor=theBackColor, fillColor=theBackColor)
+
+ drawRegionDistance = self.ChrLengthDistList[self.selectedChr]
+ self.ChrLengthDistList = [drawRegionDistance]
+ if self.plotScale == 'physic':
+ plotXScale = plotWidth / (endMb-startMb)
+ else:
+ plotXScale = plotWidth / drawRegionDistance
+
+ else: #multiple chromosome view
+ plotXScale = plotWidth / ((len(self.genotype)-1)*self.GraphInterval + drawRegionDistance)
+
+ startPosX = xLeftOffset
+ chrLabelFont=pid.Font(ttf="verdana",size=24*fontZoom,bold=0)
+
+ for i, _chr in enumerate(self.genotype):
+
+ if (i % 2 == 0):
+ theBackColor = self.GRAPH_BACK_DARK_COLOR
+ else:
+ theBackColor = self.GRAPH_BACK_LIGHT_COLOR
+
+ #draw the shaded boxes and the sig/sug thick lines
+ canvas.drawRect(startPosX, yTopOffset, startPosX + self.ChrLengthDistList[i]*plotXScale, \
+ yTopOffset+plotHeight, edgeColor=pid.gainsboro,fillColor=theBackColor)
+
+ chrNameWidth = canvas.stringWidth(_chr.name, font=chrLabelFont)
+ chrStartPix = startPosX + (self.ChrLengthDistList[i]*plotXScale -chrNameWidth)/2
+ chrEndPix = startPosX + (self.ChrLengthDistList[i]*plotXScale +chrNameWidth)/2
+
+ canvas.drawString(_chr.name, chrStartPix, yTopOffset +20,font = chrLabelFont,color=pid.dimgray)
+ COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20)
+
+ #add by NL 09-03-2010
+ HREF = "javascript:changeView(%d,%s);" % (i,self.ChrLengthMbList)
+ Areas = HT.Area(shape='rect',coords=COORDS,href=HREF)
+ gifmap.areas.append(Areas)
+ startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale
+
+ return plotXScale
+
+ # XZ: The only difference of function drawXAxisForPLINK and function drawXAxis are the function name and the self.plotScale condition.
+ def drawXAxisForPLINK(self, fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None):
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ yZero = canvas.size[1] - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ #Parameters
+ ChrLengthDistList = self.ChrLengthMbList
+ GraphInterval=self.GraphInterval
+
+ NUM_MINOR_TICKS = 5 # Number of minor ticks between major ticks
+ X_MAJOR_TICK_THICKNESS = 2
+ X_MINOR_TICK_THICKNESS = 1
+ X_AXIS_THICKNESS = 1*zoom
+
+ # ======= Alex: Draw the X-axis labels (megabase location)
+ MBLabelFont = pid.Font(ttf="verdana", size=12*fontZoom, bold=0)
+ xMajorTickHeight = 15 # How high the tick extends below the axis
+ xMinorTickHeight = 5*zoom
+ xAxisTickMarkColor = pid.black
+ xAxisLabelColor = pid.black
+ fontHeight = 12*fontZoom # How tall the font that we're using is
+ spacingFromLabelToAxis = 20
+ spacingFromLineToLabel = 3
+
+ if self.plotScale == 'physic':
+ strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont)
+ ###Physical single chromosome view
+ if self.selectedChr > -1:
+ graphMbWidth = endMb - startMb
+ XScale = Plot.detScale(startMb, endMb)
+ XStart, XEnd, XStep = XScale
+ if XStep < 8:
+ XStep *= 2
+ spacingAmtX = spacingAmt = (XEnd-XStart)/XStep
+
+ j = 0
+ while abs(spacingAmtX -int(spacingAmtX)) >= spacingAmtX/100.0 and j < 6:
+ j += 1
+ spacingAmtX *= 10
+
+ formatStr = '%%2.%df' % j
+
+ for counter, _Mb in enumerate(Plot.frange(XStart, XEnd, spacingAmt / NUM_MINOR_TICKS)):
+ if _Mb < startMb or _Mb > endMb:
+ continue
+ Xc = xLeftOffset + plotXScale*(_Mb - startMb)
+ if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark
+ canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark
+ labelStr = str(formatStr % _Mb) # What Mbase location to put on the label
+ strWidth = canvas.stringWidth(labelStr, font=MBLabelFont)
+ drawStringXc = (Xc - (strWidth / 2.0))
+ canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0)
+ else:
+ canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark
+ # end else
+
+ ###Physical genome wide view
+ else:
+ distScale = 0
+ startPosX = xLeftOffset
+ for i, distLen in enumerate(ChrLengthDistList):
+ if distScale == 0: #universal scale in whole genome mapping
+ if distLen > 75:
+ distScale = 25
+ elif distLen > 30:
+ distScale = 10
+ else:
+ distScale = 5
+ for tickdists in range(distScale, ceil(distLen), distScale):
+ canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=pid.black, width=1*zoom)
+ canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=pid.black, font=MBLabelFont, angle=270)
+ startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale
+
+ megabaseLabelFont = pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0)
+ canvas.drawString("Megabases", xLeftOffset + (plotWidth -canvas.stringWidth("Megabases", font=megabaseLabelFont))/2,
+ strYLoc + canvas.fontHeight(MBLabelFont) + 5*zoom, font=megabaseLabelFont, color=pid.black)
+ pass
+
+ canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=pid.black, width=X_AXIS_THICKNESS) # Draw the X axis itself
+
+ def drawXAxis(self, fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None):
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ yZero = canvas.size[1] - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ #Parameters
+ NUM_MINOR_TICKS = 5 # Number of minor ticks between major ticks
+ X_MAJOR_TICK_THICKNESS = 2
+ X_MINOR_TICK_THICKNESS = 1
+ X_AXIS_THICKNESS = 1*zoom
+
+ # ======= Alex: Draw the X-axis labels (megabase location)
+ MBLabelFont = pid.Font(ttf="verdana", size=12*fontZoom, bold=0)
+ xMajorTickHeight = 15 # How high the tick extends below the axis
+ xMinorTickHeight = 5*zoom
+ xAxisTickMarkColor = pid.black
+ xAxisLabelColor = pid.black
+ fontHeight = 12*fontZoom # How tall the font that we're using is
+ spacingFromLabelToAxis = 20
+ spacingFromLineToLabel = 3
+
+ if self.plotScale == 'physic':
+ strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont)
+ ###Physical single chromosome view
+ if self.selectedChr > -1:
+ graphMbWidth = endMb - startMb
+ XScale = Plot.detScale(startMb, endMb)
+ XStart, XEnd, XStep = XScale
+ if XStep < 8:
+ XStep *= 2
+ spacingAmtX = spacingAmt = (XEnd-XStart)/XStep
+
+ j = 0
+ while abs(spacingAmtX -int(spacingAmtX)) >= spacingAmtX/100.0 and j < 6:
+ j += 1
+ spacingAmtX *= 10
+
+ formatStr = '%%2.%df' % j
+
+ for counter, _Mb in enumerate(Plot.frange(XStart, XEnd, spacingAmt / NUM_MINOR_TICKS)):
+ if _Mb < startMb or _Mb > endMb:
+ continue
+ Xc = xLeftOffset + plotXScale*(_Mb - startMb)
+ if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark
+ canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark
+ labelStr = str(formatStr % _Mb) # What Mbase location to put on the label
+ strWidth = canvas.stringWidth(labelStr, font=MBLabelFont)
+ drawStringXc = (Xc - (strWidth / 2.0))
+ canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0)
+ else:
+ canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark
+ # end else
+
+ ###Physical genome wide view
+ else:
+ distScale = 0
+ startPosX = xLeftOffset
+ for i, distLen in enumerate(self.ChrLengthDistList):
+ if distScale == 0: #universal scale in whole genome mapping
+ if distLen > 75:
+ distScale = 25
+ elif distLen > 30:
+ distScale = 10
+ else:
+ distScale = 5
+ for tickdists in range(distScale, ceil(distLen), distScale):
+ canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=pid.black, width=1*zoom)
+ canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=pid.black, font=MBLabelFont, angle=270)
+ startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale
+
+ megabaseLabelFont = pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0)
+ canvas.drawString("Megabases", xLeftOffset + (plotWidth -canvas.stringWidth("Megabases", font=megabaseLabelFont))/2,
+ strYLoc + canvas.fontHeight(MBLabelFont) + 5*zoom, font=megabaseLabelFont, color=pid.black)
+ pass
+ else:
+ ChrAInfo = []
+ preLpos = -1
+ distinctCount = 0.0
+ if len(self.genotype) > 1:
+ for i, _chr in enumerate(self.genotype):
+ thisChr = []
+ Locus0CM = _chr[0].cM
+ nLoci = len(_chr)
+ if nLoci <= 8:
+ for _locus in _chr:
+ if _locus.name != ' - ':
+ if _locus.cM != preLpos:
+ distinctCount += 1
+ preLpos = _locus.cM
+ thisChr.append([_locus.name, _locus.cM-Locus0CM])
+ else:
+ for j in (0, nLoci/4, nLoci/2, nLoci*3/4, -1):
+ while _chr[j].name == ' - ':
+ j += 1
+ if _chr[j].cM != preLpos:
+ distinctCount += 1
+ preLpos = _chr[j].cM
+ thisChr.append([_chr[j].name, _chr[j].cM-Locus0CM])
+ ChrAInfo.append(thisChr)
+ else:
+ for i, _chr in enumerate(self.genotype):
+ thisChr = []
+ Locus0CM = _chr[0].cM
+ for _locus in _chr:
+ if _locus.name != ' - ':
+ if _locus.cM != preLpos:
+ distinctCount += 1
+ preLpos = _locus.cM
+ thisChr.append([_locus.name, _locus.cM-Locus0CM])
+ ChrAInfo.append(thisChr)
+
+ stepA = (plotWidth+0.0)/distinctCount
+
+ LRectWidth = 10
+ LRectHeight = 3
+ offsetA = -stepA
+ lineColor = pid.lightblue
+ startPosX = xLeftOffset
+ for j, ChrInfo in enumerate(ChrAInfo):
+ preLpos = -1
+ for i, item in enumerate(ChrInfo):
+ Lname,Lpos = item
+ if Lpos != preLpos:
+ offsetA += stepA
+ differ = 1
+ else:
+ differ = 0
+ preLpos = Lpos
+ Lpos *= plotXScale
+ if self.selectedChr > -1:
+ Zorder = i % 5
+ else:
+ Zorder = 0
+ if differ:
+ canvas.drawLine(startPosX+Lpos,yZero,xLeftOffset+offsetA,\
+ yZero+25, color=lineColor)
+ canvas.drawLine(xLeftOffset+offsetA,yZero+25,xLeftOffset+offsetA,\
+ yZero+40+Zorder*(LRectWidth+3),color=lineColor)
+ rectColor = pid.orange
+ else:
+ canvas.drawLine(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3,\
+ xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),color=lineColor)
+ rectColor = pid.deeppink
+ canvas.drawRect(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),\
+ xLeftOffset+offsetA-LRectHeight,yZero+40+Zorder*(LRectWidth+3)+LRectWidth,\
+ edgeColor=rectColor,fillColor=rectColor,edgeWidth = 0)
+ COORDS="%d,%d,%d,%d"%(xLeftOffset+offsetA-LRectHeight, yZero+40+Zorder*(LRectWidth+3),\
+ xLeftOffset+offsetA,yZero+40+Zorder*(LRectWidth+3)+LRectWidth)
+ HREF="javascript:showDatabase3('%s','%s','%s','');" % (showLocusForm,fd.RISet+"Geno", Lname)
+ Areas=HT.Area(shape='rect',coords=COORDS,href=HREF, title="Locus : " + Lname)
+ gifmap.areas.append(Areas)
+ ##piddle bug
+ if j == 0:
+ canvas.drawLine(startPosX,yZero,startPosX,yZero+40, color=lineColor)
+ startPosX += (self.ChrLengthDistList[j]+self.GraphInterval)*plotXScale
+
+ canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=pid.black, width=X_AXIS_THICKNESS) # Draw the X axis itself
+
+ def getColorForMarker(self, chrCount,flag):# no change is needed
+ chrColorDict={}
+ for i in range(chrCount):
+ if flag==1: # display blue and lightblue intercross
+ chrColorDict[i]=pid.black
+ elif flag==0:
+ if (i%2==0):
+ chrColorDict[i]=pid.blue
+ else:
+ chrColorDict[i]=pid.lightblue
+ else:#display different color for different chr
+ if i in [0,8,16]:
+ chrColorDict[i]=pid.black
+ elif i in [1,9,17]:
+ chrColorDict[i]=pid.red
+ elif i in [2,10,18]:
+ chrColorDict[i]=pid.lightgreen
+ elif i in [3,11,19]:
+ chrColorDict[i]=pid.blue
+ elif i in [4,12]:
+ chrColorDict[i]=pid.lightblue
+ elif i in [5,13]:
+ chrColorDict[i]=pid.hotpink
+ elif i in [6,14]:
+ chrColorDict[i]=pid.gold
+ elif i in [7,15]:
+ chrColorDict[i]=pid.grey
+
+ return chrColorDict
+
+
+ def drawProbeSetPosition(self, canvas, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None):
+ if len(self.traitList) != 1:
+ return
+
+ xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
+ plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
+ plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
+ yZero = canvas.size[1] - yBottomOffset
+ fontZoom = zoom
+ if zoom == 2:
+ fontZoom = 1.5
+
+ try:
+ Chr = self.traitList[0].chr # self.traitListChr =self.traitList[0].chr=_vals need to change to chrList and mbList
+ Mb = self.traitList[0].mb # self.traitListMb =self.traitList[0].mb=_vals
+ except:
+ return
+
+ if self.plotScale == 'physic':
+ if self.selectedChr > -1:
+ if self.genotype[0].name != Chr or Mb < self.startMb or Mb > self.endMb:
+ return
+ else:
+ locPixel = xLeftOffset + (Mb-self.startMb)*plotXScale
+ else:
+ locPixel = xLeftOffset
+ for i, _chr in enumerate(self.genotype):
+ if _chr.name != Chr:
+ locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale
+ else:
+ locPixel += Mb*plotXScale
+ break
+ else:
+ if self.selectedChr > -1:
+ if self.genotype[0].name != Chr:
+ return
+ else:
+ for i, _locus in enumerate(self.genotype[0]):
+ #the trait's position is on the left of the first genotype
+ if i==0 and _locus.Mb >= Mb:
+ locPixel=-1
+ break
+
+ #the trait's position is between two traits
+ if i > 0 and self.genotype[0][i-1].Mb < Mb and _locus.Mb >= Mb:
+ locPixel = xLeftOffset + plotXScale*(self.genotype[0][i-1].cM+(_locus.cM-self.genotype[0][i-1].cM)*(Mb -self.genotype[0][i-1].Mb)/(_locus.Mb-self.genotype[0][i-1].Mb))
+ break
+
+ #the trait's position is on the right of the last genotype
+ if i==len(self.genotype[0]) and Mb>=_locus.Mb:
+ locPixel = -1
+ else:
+ locPixel = xLeftOffset
+ for i, _chr in enumerate(self.genotype):
+ if _chr.name != Chr:
+ locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale
+ else:
+ locPixel += (Mb*(_chr[-1].cM-_chr[0].cM)/self.ChrLengthCMList[i])*plotXScale
+ break
+ if locPixel >= 0:
+ traitPixel = ((locPixel, yZero), (locPixel-6, yZero+12), (locPixel+6, yZero+12))
+ canvas.drawPolygon(traitPixel, edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1)
+
+ if self.legendChecked:
+ startPosY = 15
+ nCol = 2
+ smallLabelFont = pid.Font(ttf="trebuc", size=12, bold=1)
+ leftOffset = xLeftOffset+(nCol-1)*200
+ canvas.drawPolygon(((leftOffset+6, startPosY-6), (leftOffset, startPosY+6), (leftOffset+12, startPosY+6)), edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1)
+ canvas.drawString("Sequence Site", (leftOffset+15), (startPosY+5), smallLabelFont, self.TOP_RIGHT_INFO_COLOR)
+
+ # build dict based on plink result, key is chr, value is list of [snp,BP,pValue]
+ def getPlinkResultDict(self,outputFileName='',thresholdPvalue=-1,ChrOrderIdNameDict={}):
+
+ ChrList =self.ChrList
+ plinkResultDict={}
+
+ plinkResultfp = open("%s%s.qassoc"% (webqtlConfig.TMPDIR, outputFileName), "rb")
+
+ headerLine=plinkResultfp.readline()# read header line
+ line = plinkResultfp.readline()
+
+ valueList=[] # initialize value list, this list will include snp, bp and pvalue info
+ pValueList=[]
+ count=0
+
+ while line:
+ #convert line from str to list
+ lineList=self.buildLineList(line=line)
+
+ # only keep the records whose chromosome name is in db
+ if ChrOrderIdNameDict.has_key(int(lineList[0])) and lineList[-1] and lineList[-1].strip()!='NA':
+
+ chrName=ChrOrderIdNameDict[int(lineList[0])]
+ snp = lineList[1]
+ BP = lineList[2]
+ pValue = float(lineList[-1])
+ pValueList.append(pValue)
+
+ if plinkResultDict.has_key(chrName):
+ valueList=plinkResultDict[chrName]
+
+ # pvalue range is [0,1]
+ if thresholdPvalue >=0 and thresholdPvalue<=1:
+ if pValue < thresholdPvalue:
+ valueList.append((snp,BP,pValue))
+ count+=1
+
+ plinkResultDict[chrName]=valueList
+ valueList=[]
+ else:
+ if thresholdPvalue>=0 and thresholdPvalue<=1:
+ if pValue < thresholdPvalue:
+ valueList.append((snp,BP,pValue))
+ count+=1
+
+ if valueList:
+ plinkResultDict[chrName]=valueList
+
+ valueList=[]
+
+
+ line =plinkResultfp.readline()
+ else:
+ line=plinkResultfp.readline()
+
+ if pValueList:
+ minPvalue= min(pValueList)
+ else:
+ minPvalue=0
+
+ return count,minPvalue,plinkResultDict
+
+
+ ######################################################
+ # input: line: str,one line read from file
+ # function: convert line from str to list;
+ # output: lineList list
+ #######################################################
+ def buildLineList(self,line=None):
+
+ lineList = string.split(string.strip(line),' ')# irregular number of whitespaces between columns
+ lineList =[ item for item in lineList if item <>'']
+ lineList = map(string.strip, lineList)
+
+ return lineList
+
+ #added by NL: automatically generate pheno txt file for PLINK based on strainList passed from dataEditing page
+ def genPhenoTxtFileForPlink(self,phenoFileName='', RISetName='', probesetName='', valueDict={}):
+ pedFileStrainList=self.getStrainNameFromPedFile(RISetName=RISetName)
+ outputFile = open("%s%s.txt"%(webqtlConfig.TMPDIR,phenoFileName),"wb")
+ headerLine = 'FID\tIID\t%s\n'%probesetName
+ outputFile.write(headerLine)
+
+ newValueList=[]
+
+ #if valueDict does not include some strain, value will be set to -9999 as missing value
+ for item in pedFileStrainList:
+ try:
+ value=valueDict[item]
+ value=str(value).replace('value=','')
+ value=value.strip()
+ except:
+ value=-9999
+
+ newValueList.append(value)
+
+
+ newLine=''
+ for i, strain in enumerate(pedFileStrainList):
+ j=i+1
+ value=newValueList[i]
+ newLine+='%s\t%s\t%s\n'%(strain, strain, value)
+
+ if j%1000==0:
+ outputFile.write(newLine)
+ newLine=''
+
+ if newLine:
+ outputFile.write(newLine)
+
+ outputFile.close()
+
+ # get strain name from ped file in order
+ def getStrainNameFromPedFile(self, RISetName=''):
+ pedFileopen= open("%splink/%s.ped"%(webqtlConfig.HTMLPATH, RISetName),"r")
+ line =pedFileopen.readline()
+ strainNameList=[]
+
+ while line:
+ lineList=string.split(string.strip(line),'\t')
+ lineList=map(string.strip,lineList)
+
+ strainName=lineList[0]
+ strainNameList.append(strainName)
+
+ line =pedFileopen.readline()
+
+ return strainNameList
+
+ ################################################################
+ # Generate Chr list, Chr OrderId and Retrieve Length Information
+ ################################################################
+ def getChrNameOrderIdLength(self,RISet=''):
+
+ try:
+ query = """
+ Select
+ Chr_Length.Name,Chr_Length.OrderId,Length from Chr_Length, InbredSet
+ where
+ Chr_Length.SpeciesId = InbredSet.SpeciesId AND
+ InbredSet.Name = '%s'
+ Order by OrderId
+ """ % (RISet)
+ self.cursor.execute(query)
+
+ results =self.cursor.fetchall()
+ ChrList=[]
+ ChrLengthMbList=[]
+ ChrNameOrderIdDict={}
+ ChrOrderIdNameDict={}
+
+ for item in results:
+ ChrList.append(item[0])
+ ChrNameOrderIdDict[item[0]]=item[1] # key is chr name, value is orderId
+ ChrOrderIdNameDict[item[1]]=item[0] # key is orderId, value is chr name
+ ChrLengthMbList.append(item[2])
+
+ except:
+ ChrList=[]
+ ChrNameOrderIdDict={}
+ ChrLengthMbList=[]
+
+ return ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrLengthMbList
+
+
diff --git a/web/webqtl/markerRegression/__init__.py b/web/webqtl/markerRegression/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/misc/__init__.py b/web/webqtl/misc/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/misc/editHtmlPage.py b/web/webqtl/misc/editHtmlPage.py
new file mode 100755
index 00000000..68595b83
--- /dev/null
+++ b/web/webqtl/misc/editHtmlPage.py
@@ -0,0 +1,129 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import string
+import os
+import urlparse
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from utility import webqtlUtil
+
+
+#########################################
+# Edit HTML Page
+#########################################
+
+class editHtmlPage(templatePage):
+ htmlPath = webqtlConfig.ChangableHtmlPath
+
+ def __init__(self, fd):
+
+ templatePage.__init__(self, fd)
+
+ self.templateInclude = 1
+ self.dict['title'] = "Editing HTML"
+
+ if not self.updMysql():
+ return
+
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']:
+ pass
+ else:
+ heading = "Editing HTML"
+ detail = ["You don't have the permission to modify this file"]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+
+ path = fd.formdata.getvalue('path')
+ preview = fd.formdata.getvalue('preview')
+ newHtmlCode = fd.formdata.getvalue('htmlSrc')
+ if newHtmlCode:
+ #newHtmlCode = string.replace(newHtmlCode, "&image", "&image")
+ newHtmlCode = string.replace(newHtmlCode,"&", "&")
+ if path and preview:
+ #preview
+ self.templateInclude = 0
+ #print newHtmlCode
+ self.debug = newHtmlCode
+ elif path:
+ #edit result
+ fileName = self.htmlPath + path
+ newfileName = fileName +'.old'
+ os.system("/bin/cp -f %s %s" % (fileName, newfileName))
+ fp = open(fileName, 'wb')
+ fp.write(newHtmlCode)
+ fp.close()
+ #print "chown qyh %s" % fileName
+ TD_LR = HT.TD(valign="top",colspan=2,bgcolor="#eeeeee", height=200)
+ mainTitle = HT.Paragraph("Edit HTML", Class="title")
+ url = HT.Href(text = "page", url =path, Class = "normal")
+ intro = HT.Blockquote("This ",url, " has been succesfully modified. ")
+ TD_LR.append(mainTitle, intro)
+ self.dict['body'] = TD_LR
+ #elif os.environ.has_key('HTTP_REFERER'):
+ elif fd.refURL:
+ #retrieve file to be edited
+ #refURL = os.environ['HTTP_REFERER']
+ addressing_scheme, network_location, path, parameters, query, fragment_identifier = urlparse.urlparse(fd.refURL)
+ if path[-1] == "/":
+ path += 'index.html'
+
+ fileName = self.htmlPath + path
+ try:
+ fp = open(fileName,'rb')
+ except:
+ fp = open(os.path.join(self.htmlPath, 'temp.html'),'rb')
+ htmlCode = fp.read()
+ #htmlCode = string.replace(htmlCode, " "," ")
+ htmlCode = string.replace(htmlCode, "&","&")
+ fp.close()
+ form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='editHtml',submit=HT.Input(type='hidden'))
+ inputBox = HT.Textarea(name='htmlSrc', cols="100", rows=30,text=htmlCode)
+
+ hddn = {'FormID':'editHtml', 'path':path, 'preview':''}
+ for key in hddn.keys():
+ form.append(HT.Input(name=key, value=hddn[key], type='hidden'))
+ previewButton = HT.Input(type='button',name='previewhtml', value='Preview',Class="button", onClick= "editHTML(this.form, 'preview');")
+ submitButton = HT.Input(type='button',name='submitchange', value='Submit Change',Class="button", onClick= "editHTML(this.form, 'submit');")
+ resetButton = HT.Input(type='reset',Class="button")
+ form.append(HT.Center(inputBox, HT.P(), previewButton, submitButton, resetButton))
+
+ TD_LR = HT.TD(valign="top",colspan=2,bgcolor="#eeeeee")
+ mainTitle = HT.Paragraph("Edit HTML", Class="title")
+ intro = HT.Blockquote("You may edit the HTML source code in the editbox below, or you can copy the content of the editbox to your favorite HTML editor. ")
+ imgUpload = HT.Href(url="javascript:openNewWin('/upload.html', 'menubar=0,toolbar=0,location=0,resizable=0,status=1,scrollbars=1,height=400, width=600');", text="here", Class="fs14")
+ intro2 = HT.Blockquote("Click ", imgUpload, " to upload Images. ")
+ TD_LR.append(mainTitle, intro, intro2, HT.Center(form))
+ self.dict['body'] = TD_LR
+ else:
+ heading = "Editing HTML"
+ detail = ["Error occured while trying to edit the html file."]
+ self.error(heading=heading,detail=detail,error="Error")
+ return
+
diff --git a/web/webqtl/misc/uploadFilePage.py b/web/webqtl/misc/uploadFilePage.py
new file mode 100755
index 00000000..da679910
--- /dev/null
+++ b/web/webqtl/misc/uploadFilePage.py
@@ -0,0 +1,137 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+import os
+import string
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+from base import webqtlConfig
+from utility import webqtlUtil
+
+#########################################
+# Upload File Page
+#########################################
+
+class uploadFilePage(templatePage):
+
+ uploadPath = webqtlConfig.UPLOADPATH
+
+ def __init__(self, fd, formdata, cookies):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']:
+ pass
+ else:
+ heading = "Upload File"
+ detail = ["You don't have the permission to upload file to the server."]
+ self.error(heading=heading,detail=detail)
+ return
+
+ self.cursor.close()
+
+ file1 = self.save_uploaded_file (formdata, 'imgName1')
+ file2 = self.save_uploaded_file (formdata, 'imgName2')
+ file3 = self.save_uploaded_file (formdata, 'imgName3')
+ file4 = self.save_uploaded_file (formdata, 'imgName4')
+ file5 = self.save_uploaded_file (formdata, 'imgName5')
+
+ i = 0
+ uploaded = []
+
+ for filename in (file1, file2, file3, file4, file5):
+ if filename:
+ i += 1
+ uploaded.append(filename)
+
+ if i == 0:
+ heading = "Upload File"
+ detail = ["No file was selected, no file uploaded."]
+ self.error(heading=heading,detail=detail)
+ return
+ else:
+ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
+
+ imgTbl = HT.TableLite(border=0, width = "90%",cellspacing=2, cellpadding=2, align="Center")
+ imgTbl.append(HT.TR(HT.TD("Thumbnail", width="%30", align='center',Class="colorBlue"),
+ HT.TD("URL", width="%60",Class="colorBlue", align='center')))
+ for item in uploaded:
+ img = HT.Image("/images/upload/" + item, border = 0, width=80)
+
+ #url = "%s/images/upload/" % webqtlConfig.PORTADDR + item
+ #url = HT.Href(text=url, url = url, Class='normalsize', target="_blank")
+ url2 = "/images/upload/" + item
+ url2 = HT.Href(text=url2, url = url2, Class='normalsize', target="_blank")
+ imgTbl.append(HT.TR(HT.TD(img, width="%30", align='center',Class="colorWhite"),
+ #HT.TD(url, HT.BR(), 'OR', HT.BR(), url2, width="%60",Class="colorWhite", align='center')))
+ HT.TD(url2, width="%60",Class="colorWhite", align='center')))
+
+ intro = HT.Paragraph('A total of %d files are uploaded' % i)
+ TD_LR.append( HT.Center(intro) )
+
+ TD_LR.append( imgTbl )
+
+ self.dict['body'] = str(TD_LR)
+
+ def save_uploaded_file(self, form, form_field, upload_dir=""):
+ if not upload_dir:
+ upload_dir = self.uploadPath
+ if not form.has_key(form_field):
+ return None
+ fileitem = form[form_field]
+
+ if not fileitem.filename or not fileitem.file:
+ return None
+
+ seqs = [""] + range(200)
+ try:
+ newfileName = string.split(fileitem.filename, ".")
+ for seq in seqs:
+ newfileName2 = newfileName[:]
+ if seq != "":
+ newfileName2[-2] = "%s-%s" % (newfileName2[-2], seq)
+ fileExist = glob.glob(os.path.join(upload_dir, string.join(newfileName2, ".")))
+ if not fileExist:
+ break
+ except:
+ pass
+
+ newfileName = string.join(newfileName2, ".")
+ #print [newfileName, os.path.join(upload_dir, newfileName)]
+ #return
+
+ fout = file (os.path.join(upload_dir, newfileName), 'wb')
+ while 1:
+ chunk = fileitem.file.read(100000)
+ if not chunk: break
+ fout.write (chunk)
+ fout.close()
+ return newfileName
diff --git a/web/webqtl/networkGraph/GraphPage.py b/web/webqtl/networkGraph/GraphPage.py
new file mode 100755
index 00000000..b0d4063d
--- /dev/null
+++ b/web/webqtl/networkGraph/GraphPage.py
@@ -0,0 +1,46 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+class GraphPage:
+
+ def __init__(self, imagefile, mapfile):
+ # open and read the image map file
+ try:
+ mapData = open(mapfile).read()
+ except:
+ mapData = "
Unable to load image map with trait links
"
+
+ self.content = '''%s
+
+ ''' % (mapData, imagefile)
+
+ def writeToFile(self, filename):
+ """
+ Output the contents of this HTML page to a file
+ """
+ handle = open(filename, "w")
+ handle.write(self.content)
+ handle.close()
diff --git a/web/webqtl/networkGraph/ProcessedPoint.py b/web/webqtl/networkGraph/ProcessedPoint.py
new file mode 100755
index 00000000..6eb855e3
--- /dev/null
+++ b/web/webqtl/networkGraph/ProcessedPoint.py
@@ -0,0 +1,49 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+# ProcessedPoint: to store information about the relationship between
+# two particular traits
+# ProcessedPoint represents the calculations made by the program
+
+class ProcessedPoint:
+
+ def __init__(self, i, j):
+ self.i = i
+ self.j = j
+
+ def __eq__(self, other):
+ # print "ProcessedPoint: comparing %s and %s" % (self, other)
+ return (self.i == other.i and
+ self.j == other.j and
+ self.value == other.value and
+ self.color == other.color)
+
+ def __str__(self):
+ return "(%s,%s,%s,%s,%s)" % (self.i,
+ self.j,
+ self.value,
+ self.length,
+ self.color)
diff --git a/web/webqtl/networkGraph/__init__.py b/web/webqtl/networkGraph/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/web/webqtl/networkGraph/nGraphException.py b/web/webqtl/networkGraph/nGraphException.py
new file mode 100755
index 00000000..d492fca9
--- /dev/null
+++ b/web/webqtl/networkGraph/nGraphException.py
@@ -0,0 +1,33 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+class nGraphException(Exception):
+ def __init__(self, message):
+ self.message = message
+
+ def __str__(self):
+ return "Network Graph Exception: %s" % self.message
+
diff --git a/web/webqtl/networkGraph/networkGraphPage.py b/web/webqtl/networkGraph/networkGraphPage.py
new file mode 100755
index 00000000..fb4021f0
--- /dev/null
+++ b/web/webqtl/networkGraph/networkGraphPage.py
@@ -0,0 +1,335 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by NL 2010/02/11
+
+#!/usr/bin/python
+# networkGraph.py
+# Author: Stephen Pitts
+# 6/2/2004
+#
+# a script to take a matrix of data from a WebQTL job and generate a
+# graph using the neato package from GraphViz
+#
+# See graphviz for documentation of the parameters
+#
+
+
+#from mod_python import apache, util, Cookie
+#import cgi
+import tempfile
+import os
+import time
+import sys
+import cgitb
+import string
+
+from htmlgen import HTMLgen2 as HT
+
+from base.templatePage import templatePage
+import networkGraphUtils
+from base import webqtlConfig
+from utility import webqtlUtil
+from base.webqtlTrait import webqtlTrait
+import compareCorrelates.trait as smpTrait
+from GraphPage import GraphPage
+from networkGraphPageBody import networkGraphPageBody
+from correlationMatrix.tissueCorrelationMatrix import tissueCorrelationMatrix
+
+cgitb.enable()
+
+
+class networkGraphPage(templatePage):
+
+ def __init__(self,fd,InputData=None):
+
+ templatePage.__init__(self, fd)
+
+ if not self.openMysql():
+ return
+
+ if not fd.genotype:
+ fd.readGenotype()
+
+ self.searchResult = fd.formdata.getvalue('searchResult')
+
+ self.tissueProbeSetFeezeId = "1" #XZ, Jan 03, 2010: currently, this dataset is "UTHSC Illumina V6.2 RankInv B6 D2 average CNS GI average (May 08)"
+ TissueCorrMatrixObject = tissueCorrelationMatrix(tissueProbeSetFreezeId=self.tissueProbeSetFeezeId)
+
+ if type("1") == type(self.searchResult):
+ self.searchResult = string.split(self.searchResult, '\t')
+
+ if (not self.searchResult or (len(self.searchResult) < 2)):
+ heading = 'Network Graph'
+ detail = ['You need to select at least two traits in order to generate Network Graph.']
+ self.error(heading=heading,detail=detail)
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+
+ if self.searchResult:
+ if len(self.searchResult) > webqtlConfig.MAXCORR:
+ heading = 'Network Graph'
+ detail = ['In order to display Network Graph properly, Do not select more than %d traits for Network Graph.' % webqtlConfig.MAXCORR]
+ self.error(heading=heading,detail=detail)
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+ else:
+ pass
+
+ traitList = []
+ traitDataList = []
+
+ for item in self.searchResult:
+ thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
+ thisTrait.retrieveInfo()
+ thisTrait.retrieveData(fd.strainlist)
+ traitList.append(thisTrait)
+ traitDataList.append(thisTrait.exportData(fd.strainlist))
+
+ else:
+ heading = 'Network Graph'
+ detail = [HT.Font('Error : ',color='red'),HT.Font('Error occurs while retrieving data from database.',color='black')]
+ self.error(heading=heading,detail=detail)
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+
+ NNN = len(traitList)
+
+ if NNN < 2:
+ templatePage.__init__(self, fd)
+ heading = 'Network Graph'
+ detail = ['You need to select at least two traits in order to generate a Network Graph']
+ print 'Content-type: text/html\n'
+ self.write()
+ return
+ else:
+ pearsonArray = [([0] * (NNN))[:] for i in range(NNN)]
+ spearmanArray = [([0] * (NNN))[:] for i in range(NNN)]
+ GeneIdArray = []
+ GeneSymbolList = [] #XZ, Jan 03, 2011: holds gene symbols for calculating tissue correlation
+ traitInfoArray = []
+
+ i = 0
+ nnCorr = len(fd.strainlist)
+ for i, thisTrait in enumerate(traitList):
+ names1 = [thisTrait.db.name, thisTrait.name, thisTrait.cellid]
+ for j, thisTrait2 in enumerate(traitList):
+ names2 = [thisTrait2.db.name, thisTrait2.name, thisTrait2.cellid]
+ if j < i:
+ corr,nOverlap = webqtlUtil.calCorrelation(traitDataList[i],traitDataList[j],nnCorr)
+ pearsonArray[i][j] = corr
+ pearsonArray[j][i] = corr
+ elif j == i:
+ pearsonArray[i][j] = 1.0
+ spearmanArray[i][j] = 1.0
+ else:
+ corr,nOverlap = webqtlUtil.calCorrelationRank(traitDataList[i],traitDataList[j],nnCorr)
+ spearmanArray[i][j] = corr
+ spearmanArray[j][i] = corr
+
+ GeneId1 = None
+ tmpSymbol = None
+ if thisTrait.db.type == 'ProbeSet':
+ try:
+ GeneId1 = int(thisTrait.geneid)
+ except:
+ GeneId1 = 0
+ if thisTrait.symbol:
+ tmpSymbol = thisTrait.symbol.lower()
+ GeneIdArray.append(GeneId1)
+ GeneSymbolList.append(tmpSymbol)
+
+ _traits = []
+ _matrix = []
+
+ for i in range(NNN):
+ turl = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s&ProbeSetID=%s' % (traitList[i].db.name, traitList[i].name)
+ if traitList[i].cellid:
+ turl += "&CellID=%s" % traitList[i].cellid
+
+ if traitList[i].db.type == 'ProbeSet':
+ if traitList[i].symbol:
+ _symbol = traitList[i].symbol
+ else:
+ _symbol = 'unknown'
+ elif traitList[i].db.type == 'Publish':
+ _symbol = traitList[i].name
+ if traitList[i].confidential:
+ if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=traitList[i].authorized_users):
+ if traitList[i].post_publication_abbreviation:
+ _symbol = traitList[i].post_publication_abbreviation
+ else:
+ if traitList[i].pre_publication_abbreviation:
+ _symbol = traitList[i].pre_publication_abbreviation
+ else:
+ if traitList[i].post_publication_abbreviation:
+ _symbol = traitList[i].post_publication_abbreviation
+
+ #XZ, 05/26/2009: Xiaodong add code for Geno data
+ elif traitList[i].db.type == 'Geno':
+ _symbol = traitList[i].name
+ else:
+ _symbol = traitList[i].description
+ #####if this trait entered by user
+ if _symbol.__contains__('entered'):
+ _symbol = _symbol[:_symbol.index('entered')]
+ #####if this trait generaged by genenetwork
+ elif _symbol.__contains__('generated'):
+ _symbol = _symbol[_symbol.rindex(':')+1:]
+
+ newTrait = smpTrait.Trait(name=str(traitList[i]), href=turl, symbol=_symbol)
+ newTrait.color = "black"
+ _traits.append(newTrait)
+
+ for j in range(i+1, NNN):
+ dataPoint = smpTrait.RawPoint(i, j)
+ dataPoint.spearman = spearmanArray[i][j]
+ dataPoint.pearson = pearsonArray[i][j]
+
+ #XZ: get literature correlation info.
+ if GeneIdArray[i] and GeneIdArray[j]:
+ if GeneIdArray[i] == GeneIdArray[j]:
+ dataPoint.literature = 1
+ else:
+ self.cursor.execute("SELECT Value from LCorrRamin3 WHERE (GeneId1 = %d and GeneId2 = %d) or (GeneId1 = %d and GeneId2 = %d)" % (GeneIdArray[i], GeneIdArray[j], GeneIdArray[j], GeneIdArray[i]))
+ try:
+ dataPoint.literature = self.cursor.fetchone()[0]
+ except:
+ dataPoint.literature = 0
+ else:
+ dataPoint.literature = 0
+
+ #XZ: get tissue correlation info
+ if GeneSymbolList[i] and GeneSymbolList[j]:
+ dataPoint.tissue = 0
+ geneSymbolPair = []
+ geneSymbolPair.append(GeneSymbolList[i])
+ geneSymbolPair.append(GeneSymbolList[j])
+ corrArray,pvArray = TissueCorrMatrixObject.getCorrPvArrayForGeneSymbolPair(geneNameLst=geneSymbolPair)
+ if corrArray[1][0]:
+ dataPoint.tissue = corrArray[1][0]
+ else:
+ dataPoint.tissue = 0
+
+ _matrix.append(dataPoint)
+
+ OrigDir = os.getcwd()
+
+ sessionfile = fd.formdata.getvalue('session')
+
+ inputFilename = fd.formdata.getvalue('inputFile')
+
+ #If there is no sessionfile generate one and dump all matrix/trait values
+ if not sessionfile:
+ filename = webqtlUtil.generate_session()
+ webqtlUtil.dump_session([_matrix, _traits], os.path.join(webqtlConfig.TMPDIR, filename + '.session'))
+ sessionfile = filename
+
+ startTime = time.time()
+
+ #Build parameter dictionary used by networkGraphPage class using buildParamDict function
+ params = networkGraphUtils.buildParamDict(fd, sessionfile)
+
+ nodes = len(_traits)
+ rawEdges = len(_matrix)
+
+ if params["tune"] == "yes":
+ params = networkGraphUtils.tuneParamDict(params, nodes, rawEdges)
+
+ matrix = networkGraphUtils.filterDataMatrix(_matrix, params)
+
+ optimalNode = networkGraphUtils.optimalRadialNode(matrix)
+
+ if not inputFilename:
+ inputFilename = tempfile.mktemp()
+
+ inputFilename = webqtlConfig.IMGDIR + inputFilename.split("/")[2]
+
+ #writes out 4 graph files for exporting
+ graphFile = "/image/" + networkGraphUtils.writeGraphFile(matrix, _traits, inputFilename, params)
+
+ networkGraphUtils.processDataMatrix(matrix, params)
+
+ edges = 0
+
+ for edge in matrix:
+ if edge.value != 0:
+ edges +=1
+
+ for trait in _traits:
+ trait.name = networkGraphUtils.fixLabel(trait.name)
+
+ RootDir = webqtlConfig.IMGDIR
+ RootDirURL = "/image/"
+
+
+
+ #This code writes the datafile that the graphviz function runNeato uses to generate the
+ #"digraph" file that defines the graphs parameters
+ datafile = networkGraphUtils.writeNeatoFile(matrix=matrix, traits=_traits, filename=inputFilename, GeneIdArray=GeneIdArray, p=params)
+
+ #Generate graph in various file types
+ layoutfile = networkGraphUtils.runNeato(datafile, "dot", "dot", params["gType"]) # XZ, 09/11/2008: add module name
+ # ZS 03/04/2010 This second output file (layoutfile_pdf) is rotated by 90 degrees to prevent an issue with pdf output being cut off at the edges
+ layoutfile_pdf = networkGraphUtils.runNeato(datafile + "_pdf", "dot", "dot", params["gType"]) # ZS 03/04/2010
+ pngfile = networkGraphUtils.runNeato(layoutfile, "png", "png", params["gType"])
+ mapfile = networkGraphUtils.runNeato(layoutfile, "cmapx", "cmapx", params["gType"])# XZ, 09/11/2008: add module name
+ giffile = networkGraphUtils.runNeato(layoutfile, "gif", "gif", params["gType"])# XZ, 09/11/2008:add module name
+ psfile = networkGraphUtils.runNeato(layoutfile_pdf, "ps", "ps", params["gType"])# XZ, 09/11/2008: add module name
+ pdffile = networkGraphUtils.runPsToPdf(psfile, params["width"], params["height"])# XZ, 09/11/2008: add module name
+
+ #This generates text files in XGGML (standardized graphing language) and plain text
+ #so the user can create his/her own graphs in a program like Cytoscape
+
+ htmlfile1 = datafile + ".html"
+ htmlfile2 = datafile + ".graph.html"
+
+ os.chdir(OrigDir)
+
+ #This generates the graph in various image formats
+ giffile = RootDirURL + giffile
+ pngfile = RootDirURL + pngfile
+ pdffile = RootDirURL + pdffile
+ endTime = time.time()
+ totalTime = endTime - startTime
+
+ os.chdir(RootDir)
+
+ page2 = GraphPage(giffile, mapfile)
+ page2.writeToFile(htmlfile2)
+
+ #This generates the HTML for the body of the Network Graph page
+ page1 = networkGraphPageBody(fd, matrix, _traits, htmlfile2, giffile, pdffile, nodes, edges, rawEdges, totalTime, params, page2.content, graphFile, optimalNode)
+
+ #Adds the javascript colorSel to the body to allow line color selection
+ self.dict["js1"] = ' '
+ #self.dict["js1"] += ''
+
+ #Set body of current templatePage to body of the templatePage networkGraphPage
+ self.dict['body'] = page1.dict['body']
+
+
diff --git a/web/webqtl/networkGraph/networkGraphPageBody.py b/web/webqtl/networkGraph/networkGraphPageBody.py
new file mode 100644
index 00000000..22b49ccd
--- /dev/null
+++ b/web/webqtl/networkGraph/networkGraphPageBody.py
@@ -0,0 +1,697 @@
+# Copyright (C) University of Tennessee Health Science Center, Memphis, TN.
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# This program is available from Source Forge: at GeneNetwork Project
+# (sourceforge.net/projects/genenetwork/).
+#
+# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010)
+# at rwilliams@uthsc.edu and xzhou15@uthsc.edu
+#
+#
+#
+# This module is used by GeneNetwork project (www.genenetwork.org)
+#
+# Created by GeneNetwork Core Team 2010/08/10
+#
+# Last updated by GeneNetwork Core Team 2010/10/20
+
+from base.templatePage import templatePage
+import networkGraphUtils
+from base import webqtlConfig
+
+
+# our output representation is fairly complicated
+# because we use an iframe to represent the image and the image has
+# an associated image map, our output is actually three files
+# 1) a networkGraphPage instance -- the URL we pass to the user
+# 2) a GraphPage with the image map and the graph -- this page has to be
+# there to pass the imagemap data to the browser
+# 3) a PNG graph file itself
+
+class networkGraphPageBody(templatePage):
+ """
+ Using the templatePage class, we build an HTML shell for the graph
+ that displays the parameters used to generate it and allows the
+ user to redraw the graph with different parameters.
+
+ The way templatePage works, we build the page in pieces in the __init__
+ method and later on use the inherited write method to render the page.
+ """
+
+ def __init__(self, fd, matrix, traits, imageHtmlName, imageName, pdfName, nodes,
+ edges, rawEdges, totalTime, p, graphcode, graphName, optimalNode):
+
+ templatePage.__init__(self, fd)
+
+ if p["printIslands"] == 0:
+ island = "Only nodes with edges"
+ else:
+ island = "All nodes"
+
+ body = """
Network Graph
+
The %s nodes in the
+ graph below show the selected traits. %s are displayed. The
+ %s edges between the nodes, filtered from the %s total edges and
+ drawn as %s, show %s correlation
+ coefficients greater than %s or less than -%s. The graph\'s
+ canvas is %s by %s cm, and the node
+ labels are drawn with a %s point font, and the edge
+ labels are drawn with a %s point font. Right-click or control-click
+ on the graph to save it to disk for further manipulation. See
+ below for the trait key, and graph options.
+ """ % (nodes, island, edges, rawEdges,
+ p["splineName"], p["correlationName"],
+ p["kValue"],
+ p["kValue"],
+ p["width"],
+ p["height"],
+ p["nfontsize"],
+ p["cfontsize"])
+
+ #Generate a list of symbols for the central node selection drop-down menu
+
+ symbolList = networkGraphUtils.generateSymbolList(traits)
+
+ #Some of these hidden variables (CellID, CellID2, ProbesetID2, etc) exist
+ #to be used by the javascript functions called when a user clicks on an edge or node
+
+ formParams = '''
+
+