about summary refs log tree commit diff
path: root/web/webqtl/networkGraph
diff options
context:
space:
mode:
authorroot2012-05-08 18:39:56 -0500
committerroot2012-05-08 18:39:56 -0500
commitea46f42ee640928b92947bfb204c41a482d80937 (patch)
tree9b27a4eb852d12539b543c3efee9d2a47ef470f3 /web/webqtl/networkGraph
parent056b5253fc3857b0444382aa39944f6344dc1ceb (diff)
downloadgenenetwork2-ea46f42ee640928b92947bfb204c41a482d80937.tar.gz
Add all the source codes into the github.
Diffstat (limited to 'web/webqtl/networkGraph')
-rwxr-xr-xweb/webqtl/networkGraph/GraphPage.py46
-rwxr-xr-xweb/webqtl/networkGraph/ProcessedPoint.py49
-rwxr-xr-xweb/webqtl/networkGraph/__init__.py0
-rwxr-xr-xweb/webqtl/networkGraph/nGraphException.py33
-rwxr-xr-xweb/webqtl/networkGraph/networkGraphPage.py335
-rw-r--r--web/webqtl/networkGraph/networkGraphPageBody.py697
-rw-r--r--web/webqtl/networkGraph/networkGraphUtils.py750
7 files changed, 1910 insertions, 0 deletions
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 =  "<p><b>Unable to load image map with trait links</b></p>"
+
+        self.content = '''%s
+        <img border="0" alt="the graph" src="%s" usemap="#webqtlGraph" />
+        ''' % (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
--- /dev/null
+++ b/web/webqtl/networkGraph/__init__.py
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"] = '<SCRIPT SRC="/javascript/colorSel.js"></SCRIPT><BR>'   
+            #self.dict["js1"] += '<SCRIPT SRC="/javascript/networkGraph.js"></SCRIPT>' 
+                        
+            #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 = """ <td><P class='title'>Network Graph</P>
+        <Blockquote><p>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 <b>%s</b> 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.</p>
+        """ % (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 = '''
+        
+        <form name="showDatabase" action="%s%s" METHOD="POST"  enctype="multipart/form-data">
+        
+        <input type="hidden" name="filename" value="%s" />
+        <input type="hidden" name="exportFilename" value="%s" />
+        <input type="hidden" name="progress" value="1" />
+        <input type="hidden" name="database" value="_" />
+        <input type="hidden" name="database2" value="_" />
+        <input type="hidden" name="ProbeSetID" value="_" />
+        <input type="hidden" name="ProbeSetID2" value="_" />
+        <input type="hidden" name="CellID" value="_" />
+        <input type="hidden" name="CellID2" value="_" />
+        <input type="hidden" name="tune" value="no" />
+        <input type="hidden" name="ShowLine" value="ON">
+        <input type="hidden" name="ShowStrains" value="ON">
+        <input type="hidden" name="FormID" value="showDatabase" />
+        <input type="hidden" name="RISet" value="%s" />
+        <input type="hidden" name="incparentsf1" value="ON" />
+        <input type="hidden" name="session" value="%s" />
+        <input type="hidden" name="searchResult" id="searchResult" value="%s" />
+        <input type="hidden" name="symbolList" id="symbolList" value="%s" />
+        <input type="hidden" name="optimalNode" id="optimalNode" value="%s" />
+        <input type="hidden" name="rankOrder" id="rankOrder" value="_" />
+        <input type="hidden" name="X_geneID" id="X_geneID" value="_" />
+        <input type="hidden" name="Y_geneID" id="Y_geneID" value="_" />
+        <input type="hidden" name="X_geneSymbol" id="X_geneSymbol" value="_" />
+        <input type="hidden" name="Y_geneSymbol" id="Y_geneSymbol" value="_" />
+        <input type="hidden" name="TissueProbeSetFreezeId" id="TissueProbeSetFreezeId" value="1" />
+        ''' % (webqtlConfig.CGIDIR,
+               webqtlConfig.SCRIPTFILE,
+               p["filename"],
+               graphName,
+               p["riset"],
+               p["session"],
+               p["searchResult"],
+               symbolList,
+               optimalNode)
+        
+        body += formParams
+        
+        #Adds the html generated by graphviz that displays the graph itself
+        body += graphcode
+
+        #Initializes all form values
+
+        selected = ["","","",""]
+        selected[p["whichValue"]] = "CHECKED"
+
+        selected3 = ["",""]
+        if p["splines"] == "yes":
+            selected3[0] = "CHECKED"
+        else:
+            selected3[1] = "CHECKED"
+
+        selected5 = ["",""]
+        if p["nodeshape"] == "yes":
+            selected5[0] = "CHECKED"
+        else:
+            selected5[1] = "CHECKED"
+            
+        selected7 = ["",""]
+        if p["nodelabel"] == "yes":
+            selected7[0] = "CHECKED"
+        else:
+            selected7[1] = "CHECKED"
+            
+        selected6 = ["",""]
+        if p["dispcorr"] == "yes":
+            selected6[0] = "CHECKED"
+        else:
+            selected6[1] = "CHECKED"
+
+        selected4 = ["", ""]
+        selected4[p["printIslands"]] = "CHECKED"
+       
+        selectedExportFormat = ["",""]
+        if p["exportFormat"] == "xgmml":
+            selectedExportFormat[0] = "selected='selected'"
+        elif p["exportFormat"] == "plain":
+            selectedExportFormat[1] = "selected='selected'"
+        
+        selectedTraitType = ["",""]
+        if p["traitType"] == "symbol":
+            selectedTraitType[0] = "selected='selected'"
+        elif p["traitType"] == "name":
+            selectedTraitType[1] = "selected='selected'"
+
+	selectedgType = ["","","","",""]
+	if p["gType"] == "none":
+	    selectedgType[0] = "selected='selected'"
+        elif p["gType"] == "neato":
+            selectedgType[1] = "selected='selected'"
+	elif p["gType"] == "fdp":
+	    selectedgType[2] = "selected='selected'"
+	elif p["gType"] == "circular":
+	    selectedgType[3] = "selected='selected'"
+	elif p["gType"] == "radial":
+	    selectedgType[4] = "selected='selected'"	
+ 
+ 
+        selectedLock = ["",""]
+        if p["lock"] == "no":
+            selectedLock[0] = "selected='selected'"
+        elif p["lock"] == "yes":
+            selectedLock[1] = "selected='selected'"
+ 
+        # line 1~6
+        
+        selectedL1style = ["","","","",""]
+        if p["L1style"] == "":
+            selectedL1style[0] = "selected='selected'"
+        elif p["L1style"] == "bold":
+            selectedL1style[1] = "selected='selected'"
+        elif p["L1style"] == "dotted":
+            selectedL1style[2] = "selected='selected'"
+        elif p["L1style"] == "dashed":
+            selectedL1style[3] = "selected='selected'"
+        else:
+            selectedL1style[4] = "selected='selected'"
+        
+        selectedL2style = ["","","","",""]
+        if p["L2style"] == "":
+            selectedL2style[0] = "selected='selected'"
+        elif p["L2style"] == "bold":
+            selectedL2style[1] = "selected='selected'"
+        elif p["L2style"] == "dotted":
+            selectedL2style[2] = "selected='selected'"
+        elif p["L2style"] == "dashed":
+            selectedL2style[3] = "selected='selected'"
+        else:
+            selectedL2style[4] = "selected='selected'"
+        
+        selectedL3style = ["","","","",""]
+        if p["L3style"] == "":
+            selectedL3style[0] = "selected='selected'"
+        elif p["L3style"] == "bold":
+            selectedL3style[1] = "selected='selected'"
+        elif p["L3style"] == "dotted":
+            selectedL3style[2] = "selected='selected'"
+        elif p["L3style"] == "dashed":
+            selectedL3style[3] = "selected='selected'"
+        else:
+            selectedL3style[4] = "selected='selected'"
+        
+        selectedL4style = ["","","","",""]
+        if p["L4style"] == "":
+            selectedL4style[0] = "selected='selected'"
+        elif p["L4style"] == "bold":
+            selectedL4style[1] = "selected='selected'"
+        elif p["L4style"] == "dotted":
+            selectedL4style[2] = "selected='selected'"
+        elif p["L4style"] == "dashed":
+            selectedL4style[3] = "selected='selected'"
+        else:
+            selectedL4style[4] = "selected='selected'"
+        
+        selectedL5style = ["","","","",""]
+        if p["L5style"] == "":
+            selectedL5style[0] = "selected='selected'"
+        elif p["L5style"] == "bold":
+            selectedL5style[1] = "selected='selected'"
+        elif p["L5style"] == "dotted":
+            selectedL5style[2] = "selected='selected'"
+        elif p["L5style"] == "dashed":
+            selectedL5style[3] = "selected='selected'"
+        else:
+            selectedL5style[4] = "selected='selected'"
+        
+        selectedL6style = ["","","","",""]
+        if p["L6style"] == "":
+            selectedL6style[0] = "selected='selected'"
+        elif p["L6style"] == "bold":
+            selectedL6style[1] = "selected='selected'"
+        elif p["L6style"] == "dotted":
+            selectedL6style[2] = "selected='selected'"
+        elif p["L6style"] == "dashed":
+            selectedL6style[3] = "selected='selected'"
+        else:
+            selectedL6style[4] = "selected='selected'"
+            
+        nfontSelected = ["", "", ""]
+        if p["nfont"] == "arial":
+            nfontSelected[0] = "selected='selected'"
+        elif p["nfont"] == "verdana":
+            nfontSelected[1] = "selected='selected'"
+        elif p["nfont"] == "times":
+            nfontSelected[2] = "selected='selected'"
+            
+        cfontSelected = ["", "", ""]
+        if p["cfont"] == "arial":
+            cfontSelected[0] = "selected='selected'"
+        elif p["cfont"] == "verdana":
+            cfontSelected[1] = "selected='selected'"
+        elif p["cfont"] == "times":
+            cfontSelected[2] = "selected='selected'"
+ 
+        #Writes the form part of the body
+ 
+        body += ''' <br><br>
+        <TABLE cellspacing=0 Cellpadding=0>
+        <TR>
+        <TD class="doubleBorder">
+       
+        <Table Cellpadding=3>
+        
+        <tr><td align="left">
+        <dd>
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+        <input type="submit" name="mintmap" value="    Redraw    " class="button" onClick="return sortSearchResults(this.form);" />
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+        <input TYPE="Button" class="button" value="    Info    " onclick="javascript:window.open('/networkGraphInfo.html', '_blank');">
+        </dd>
+        </td></tr>
+        
+        <tr><td align='center' colspan='2'><hr size='1'></td></tr>
+    <tr>
+		<tr align='left' valign='top'>
+		    <td align='left'>
+		    &nbsp;<select align='left' name='gType' id='gType' onchange='addTraitSelection();'>
+		    <option value='none' %s>Select Graph Method</option>
+			<option value='neato' %s>Spring Model Layout (energy reduction)</option>
+			<option value='fdp' %s>Spring Model Layout (force reduction)</option>
+			<option value='circular' %s>Circular Layout</option>
+			<option value='radial' %s>Radial Layout</option>
+		    </select>
+		    <div align="left" id='nodeSelect'> </div>
+		    </td>
+		</tr>
+	</tr>
+	
+	    <tr><td align='center' colspan='2'><hr size='1'></td></tr>
+	    
+    <tr><td align='center' colspan='2'>
+
+        <table width='100%%'>
+
+        <tr align='left'>
+            <td>Lock Graph Structure</td>
+            <td align='left'><select name='lock' id='lock' onChange="changeThreshold();">
+            <option value='no' %s>No</option>
+            <option value='yes' %s>Yes</option>
+            </select></td>
+        </tr>
+        <tr><td align='left' colspan='2' nowrap='nowrap'>
+        Locking the graph structure allows the user to hold the position of<br>
+        all nodes and the length of all edges constant, letting him/her easily<br>
+        compare between different correlation types. Changing the value to "yes"<br> 
+        requires the line threshold to be set to 0 in order to lock the structure.<br>
+        </td></tr>
+        </td>
+    </tr>
+	
+	
+	<tr><td align='center' colspan='2'><hr size='1'></td></tr>        
+
+        <tr><td align='center' colspan='2'>
+            
+                <table width='100%%'>
+                
+                <tr align='center'>
+                    <td>Line Type 1:</td>
+                    <td>-1</td>
+                    <td>to</td>
+                    <td>-0.7</td>
+                    <td><Input type=radio name=colorS value="cL1" checked></TD>
+                    <td bgcolor="%s" ID="cL1" width=20></td>
+                    <td><select name='L1style'>
+                        <option value='' %s>normal</option>
+                        <option value='bold' %s>bold</option>
+                        <option value='dotted' %s>dotted</option>
+                        <option value='dashed' %s>dashed</option>
+                        <option value='invis' %s>invisible</option>
+                    </select></td>
+                </tr>
+                
+                <tr align='center'>
+                    <td>Line Type 2:</td>
+                    <td>-0.7</td>
+                    <td>to</td>
+                    <td>-0.5</td>
+                    <td><Input type=radio name=colorS value="cL2"></TD>
+                    <Td bgcolor="%s" ID="cL2" width=20></td>
+                    <td><select name='L2style'>
+                        <option value='' %s>normal</option>
+                        <option value='bold' %s>bold</option>
+                        <option value='dotted' %s>dotted</option>
+                        <option value='dashed' %s>dashed</option>
+                        <option value='invis' %s>invisible</option>
+                    </select></td>
+                </tr>
+                
+                <tr align='center'>
+                    <td>Line Type 3:</td>
+                    <td>-0.5</td>
+                    <td>to</td>
+                    <td>0</td>
+                    <td><Input type=radio name=colorS value="cL3"></TD>
+                    <Td bgcolor="%s" ID="cL3" width=20></td>
+                    <td><select name='L3style'>
+                        <option value='' %s>normal</option>
+                        <option value='bold' %s>bold</option>
+                        <option value='dotted' %s>dotted</option>
+                        <option value='dashed' %s>dashed</option>
+                        <option value='invis' %s>invisible</option>
+                    </select></td>
+                </tr>
+                
+                <tr align='center'>
+                    <td>Line Type 4:</td>
+                    <td>0</td>
+                    <td>to</td>
+                    <td>0.5</td>
+                    <td><Input type=radio name=colorS value="cL4"></TD>
+                    <Td bgcolor="%s" ID="cL4" width=20></td>
+                    <td><select name='L4style'>
+                        <option value='' %s>normal</option>
+                        <option value='bold' %s>bold</option>
+                        <option value='dotted' %s>dotted</option>
+                        <option value='dashed' %s>dashed</option>
+                        <option value='invis' %s>invisible</option>
+                    </select></td>
+                </tr>
+                
+                <tr align='center'>
+                    <td>Line Type 5:</td>
+                    <td>0.5</td>
+                    <td>to</td>
+                    <td>0.7</td>
+                    <td><Input type=radio name=colorS value="cL5"></TD>
+                    <Td bgcolor="%s" ID="cL5" width=20></td>
+                    <td><select name='L5style'>
+                        <option value='' %s>normal</option>
+                        <option value='bold' %s>bold</option>
+                        <option value='dotted' %s>dotted</option>
+                        <option value='dashed' %s>dashed</option>
+                        <option value='invis' %s>invisible</option>
+                    </select></td>
+                </tr>
+                
+                <tr align='center'>
+                    <td>Line Type 6:</td>
+                    <td>0.7</td>
+                    <td>to</td>
+                    <td>1</td>
+                    <td><Input type=radio name=colorS value="cL6"></TD>
+                    <Td bgcolor="%s" ID="cL6" width=20></td>
+                    <td><select name='L6style'>
+                        <option value='' %s>normal</option>
+                        <option value='bold' %s>bold</option>
+                        <option value='dotted' %s>dotted</option>
+                        <option value='dashed' %s>dashed</option>
+                        <option value='invis' %s>invisible</option>
+                    </select></td>
+                </tr>
+                
+                </table>
+            </td>
+        </tr>
+        
+        <tr><td align='center' colspan='2' nowrap='nowrap'>To change colors, select Line Type then select Color below.</td></tr>
+        
+        <tr><td align='center' colspan='2'><hr size='1'></td></tr>
+        
+        <tr>
+            <TD align="right">Correlation Type:</TD>
+            <TD>
+                <table border='0' cellspacing='0' cellpadding='0' width='100%%'>
+                    <tr>
+                        <td><Input type="radio" name="whichValue" value="0" %s>Pearson</td>
+                        <td><Input type="radio" name="whichValue" value="1" %s>Spearman</td>
+                        <td rowspan=2 align="center"><input TYPE="Button" class="button" value="Info" onclick="javascript:window.open('/correlationAnnotation.html', '_blank');"></td>
+                    </tr>
+                    <tr>
+                        <td><Input type="radio" name="whichValue" value="2" %s>Literature</td>
+                        <td><Input type="radio" name="whichValue" value="3" %s>Tissue</td>
+                    </tr>
+                </table>
+            </TD>
+        </TR>
+        
+        <TR>
+            <TD align="right" NOWRAP>Line Threshold:</TD>
+            <TD NOWRAP>Absolute values greater than <input size="5" name="kValue" id="kValue" value="%s"></TD>
+        </TR>
+        
+        <tr><td align='center' colspan='2'><hr size='1'></td></tr>
+        
+        <TR>
+            <TD align="right">Draw Nodes :</TD>
+            <TD NOWRAP>
+                <Input type="radio" name="printIslands" value="1" %s>all
+                <Input type="radio" name="printIslands" value="0" %s>connected only
+            </TD>
+        </TR>
+        
+        <TR>
+            <TD align="right">Node Shape:</TD>
+            <TD>
+                <Input type="radio" name="nodeshape" value="yes" %s>rectangle
+                <Input type="radio" name="nodeshape" value="no" %s>ellipse
+            </TD>
+        </TR>
+        
+        <TR>
+            <TD align="right">Node Label:</TD>
+            <TD>
+                <Input type="radio" name="nodelabel" value="yes" %s>trait name<br>
+                <Input type="radio" name="nodelabel" value="no" %s>gene symbol / marker name
+            </TD>
+        </TR>
+        
+        <tr>
+            <td align="right">Node Font:</td>
+            <TD>
+                <select name='nfont'>
+                    <option value='Arial' %s>Arial</option>
+                    <option value='Verdana' %s>Verdana</option>
+                    <option value='Times' %s>Times</option>
+                </select>
+            </TD>
+        </TR>
+        
+        <tr>
+            <td align="right">Node Font Size:</td>
+            <TD><input size="5" name="nfontsize" value="%s"> point</TD>
+        </TR>
+        
+        <tr><td align='center' colspan='2'><hr size='1'></td></tr>
+        
+        <TR>
+            <TD align="right">Draw Lines:</TD>
+            <TD>
+                <Input type="radio" name="splines" value="yes" %s>curved
+                <Input type="radio" name="splines" value="no" %s>straight
+            </TD>
+        </TR>
+        
+        <TR>
+            <TD align="right">Display Correlations:</TD>
+            <TD>
+                <Input type="radio" name="dispcorr" value="no" %s>no
+                <Input type="radio" name="dispcorr" value="yes" %s>yes
+            </TD>
+        </tr>
+        
+        <tr>
+            <td align="right">Line Font:</td>
+            <TD>
+                <select name='cfont'>
+                    <option value='Arial' %s>Arial</option>
+                    <option value='Verdana' %s>Verdana</option>
+                    <option value='Times' %s>Times</option>
+                </select>
+            </TD>
+        </TR>
+        
+        <TR>
+            <TD align="right" nowrap="nowrap">Line Font Size:</TD>
+            <TD><input size="5" name="cfontsize" value="%s"> point</TD>
+        </TR>
+        
+        <tr><td align='center' colspan='2'><hr size='1'></td></tr>
+        
+        <TR><TD colspan = 2>
+        
+        <Input type=hidden name=cPubName value="%s">
+        <Input type=hidden name=cMicName value="%s">
+        <Input type=hidden name=cGenName value="%s">
+        
+        <Input type=hidden name=cPubColor value="%s">
+        <Input type=hidden name=cMicColor value="%s">
+        <Input type=hidden name=cGenColor value="%s">
+        
+        <Input type=hidden name=cL1Name value="%s">
+        <Input type=hidden name=cL2Name value="%s">
+        <Input type=hidden name=cL3Name value="%s">
+        <Input type=hidden name=cL4Name value="%s">
+        <Input type=hidden name=cL5Name value="%s">
+        <Input type=hidden name=cL6Name value="%s">
+        
+        <Input type=hidden name=cL1Color value="%s">
+        <Input type=hidden name=cL2Color value="%s">
+        <Input type=hidden name=cL3Color value="%s">
+        <Input type=hidden name=cL4Color value="%s">
+        <Input type=hidden name=cL5Color value="%s">
+        <Input type=hidden name=cL6Color value="%s">
+        
+        <Input type=hidden id=initThreshold value="0.5">
+        
+		<Table CellSpacing = 3>
+			<tr>
+			    <TD><Input type=radio name=colorS value="cPub"> Publish </TD>
+			    <Td bgcolor="%s" ID="cPub" width=20 height=10></td>
+			    <TD><Input type=radio name=colorS value="cMic"> Microarray </TD>
+			    <Td bgcolor="%s" ID="cMic" width=20 height=10></td>
+			    <TD><Input type=radio name=colorS value="cGen"> Genotype </TD>
+			    <Td bgcolor="%s" ID="cGen" width=20 height=10></td>
+			</tr>
+		</table>
+		
+		</td></tr>
+		
+		<tr><td align='center' colspan='2'><hr size='1'></td></tr>
+		
+		<tr>
+		    <td colspan='2' align='center'>
+		        <img NAME="colorPanel" src="/images/colorPanel.png" alt="colorPanel" onClick="clickHandler(event, this);">
+		    </TD>
+		</TR>
+		
+		<tr><td align='center' colspan='2'><hr size='1'></td></tr>
+		
+		<tr><td align='center' colspan='2'><input type="submit" name="mintmap" value="    Redraw Graph    " class="button" onClick="return sortSearchResults(this.form);"/></td></tr>
+        
+        </TABLE>
+        </form></TD>
+        <SCRIPT type="text/javascript" SRC="/javascript/networkGraph.js"></SCRIPT>
+        ''' % (selectedgType[0], selectedgType[1], selectedgType[2], selectedgType[3], selectedgType[4],
+                           selectedLock[0], selectedLock[1],
+                           p["cL1Color"],
+                           selectedL1style[0], selectedL1style[1], selectedL1style[2], selectedL1style[3], selectedL1style[4],
+                           p["cL2Color"],
+                           selectedL2style[0], selectedL2style[1], selectedL2style[2], selectedL2style[3], selectedL2style[4],
+                           p["cL3Color"],
+                           selectedL3style[0], selectedL3style[1], selectedL3style[2], selectedL3style[3], selectedL3style[4],
+                           p["cL4Color"],
+                           selectedL4style[0], selectedL4style[1], selectedL4style[2], selectedL4style[3], selectedL4style[4],
+                           p["cL5Color"],
+                           selectedL5style[0], selectedL5style[1], selectedL5style[2], selectedL5style[3], selectedL5style[4],
+                           p["cL6Color"],
+                           selectedL6style[0], selectedL6style[1], selectedL6style[2], selectedL6style[3], selectedL6style[4],
+                           selected[0], selected[1], selected[2], selected[3],
+                           p["kValue"], 
+                           selected4[1], selected4[0], 
+                           selected5[0], selected5[1], 
+                           selected7[0], selected7[1],
+                           nfontSelected[0], nfontSelected[1], nfontSelected[2],
+                           p["nfontsize"],
+                           selected3[0], selected3[1], 
+                           selected6[1], selected6[0],
+                           cfontSelected[0], cfontSelected[1], cfontSelected[2],
+                           p["cfontsize"],
+                           p["cPubName"], p["cMicName"], p["cGenName"],
+                           p["cPubColor"], p["cMicColor"], p["cGenColor"],
+                           p["cL1Name"], p["cL2Name"], p["cL3Name"], p["cL4Name"], p["cL5Name"], p["cL6Name"],
+                           p["cL1Color"], p["cL2Color"], p["cL3Color"], p["cL4Color"], p["cL5Color"], p["cL6Color"],
+                           p["cPubColor"], p["cMicColor"], p["cGenColor"])
+        
+		#updated by NL 09-03-2010 function changeFormat() has been moved to webqtl.js and be changed to changeFormat(graphName)
+        #Javascript that selects the correct graph export file given what the user selects 
+        #from the two drop-down menus
+
+        body += ''' <td width='10'>&nbsp;</td> 
+        <TD valign="top"><p>Right-click or control-click on the following
+        links to download this graph as a <a href="%s" class="normalsize" target="_blank">GIF file</a> or
+        a <a href="%s" class="normalsize" target="_blank">PDF file</a>.</p> ''' % (imageName, pdfName)
+        
+        body += ''' <p>Initial edge lengths were computed by applying an r-to-Z transform to the correlation coefficents
+        and then inverting the results. The graph drawing algorithm
+        found a configuration that minimizes the total stretching of the edges.</p> ''' 
+        
+        body += ''' <p>This graph took %s seconds to generate with the <a href="http://www.research.att.com/sw/tools/graphviz/" class="normalsize" target="_blank">
+        GraphViz</a> visualization toolkit from <a href="http://www.research.att.com" class="normalsize" target="_blank">AT&amp;T Research</a>.</p>''' % (round(totalTime, 2))
+        
+        #Form to export graph file as either XGMML (standardized graphing format) or a
+        #plain text file with trait names/symbols and correlations
+        
+        body += '''
+        <form name="graphExport">
+        <p>Export Graph File:</p>
+        <p><select name='exportFormat' id='exportFormat' onchange='changeFormat("%s")'>
+            <option value='plain' %s>Plain Text Format</option>
+            <option value='xgmml' %s>XGMML Format</option>
+        </select>
+        &nbsp&nbsp&nbsp&nbsp&nbsp
+        <select name='traitType' id='traitType' onchange='changeFormat("%s")'>
+            <option value='symbol' %s>Trait Symbol</option>
+            <option value='name' %s>Full Trait Name</option>
+        </select></p>
+        
+        <p>
+        <input type="button" class="button" name="exportGraphFile" value="   Export Graph File   "/>
+        </p>
+        </form> 
+        ''' % (graphName, selectedExportFormat[0], selectedExportFormat[1],
+               graphName, selectedTraitType[0], selectedTraitType[1])
+
+        body += '''</Blockquote></td>
+        </TR></TABLE> 
+        <form method="get" action="http://www.google.com/search">
+        <input type="text"   name="q" size="31" maxlength="255" value="" />
+        <input type="submit" value="Google Search" />
+        <input type="radio"  name="sitesearch" value="" /> The Web
+        <input type="radio"  name="sitesearch" value="genenetwork.org" checked /> GeneNetwork <br />
+        </form>
+        ''' 
+
+        
+        self.dict["body"] = body
+
+    def writeToFile(self, filename):
+        """
+        Output the contents of this HTML page to a file.
+        """
+        handle = open(filename, "w")
+        handle.write(str(self))
+        handle.close()
diff --git a/web/webqtl/networkGraph/networkGraphUtils.py b/web/webqtl/networkGraph/networkGraphUtils.py
new file mode 100644
index 00000000..fd0e7484
--- /dev/null
+++ b/web/webqtl/networkGraph/networkGraphUtils.py
@@ -0,0 +1,750 @@
+# 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
+
+# graphviz:
+# a library for sending trait data to the graphviz utilities to get
+# graphed
+
+# ParamDict: a dictionary of strings that map to strings where the keys are
+#     valid parameters and the values are validated versions of those parameters
+#
+# The list below also works for visualize.py; different parameters apply to different
+# functions in the pipeline. See visualize.py for more details.
+#
+# parameters:
+# filename: an input file with comma-delimited data to visualize
+# kValue:
+#    how to filter the edges; edges with correlation coefficents in
+#    [-k, k] are not drawn
+# whichValue: which of the two correlation coefficents are used;
+#     0 means the top half (pearson) and
+#     1 means the bottom half (spearman)
+# width: the width of the graph in inches
+# height: the height of the graph in inches
+# --scale: an amount to multiply the length factors by to space out the nodes
+# spline: whether to use splines instead of straight lines to draw graphs
+# tune: whether to automatically pick intelligent default values for
+#     kValue and spline based on the number of edges in the input data
+# whichVersion: whether to display the graph zoomed or fullscreen
+#     0 means zoom
+#     1 means fullscreen
+# printIslands: whether to display nodes with no visible edges
+# 
+
+# DataMatrix: a one-dimensional array of DataPoints in sorted order by i first
+
+
+
+import copy
+import os
+#import os.path
+import math
+import string
+
+from base import webqtlConfig
+from utility import webqtlUtil
+#import trait
+from nGraphException import nGraphException
+from ProcessedPoint import ProcessedPoint
+
+
+# processDataMatrix: DataMatrix -> ParamDict -> void
+# this is the second part after filterDataMatrix
+# To process the set of points in a DataMatrix as follows
+#    1) choose an appropriate color for the data point
+#    2) filter those between k values
+#    3) to use an r-to-Z transform to spread out the correlation
+#       values from [-1,1] to (-inf, inf)
+#    4) to invert the values so that higher correlations result in
+#       shorter edges
+#
+# Note: this function modifies the matrix in-place. My functional
+# programming instincts tell me that this is a bad idea.
+def processDataMatrix(matrix, p):
+    for pt2 in matrix:
+        # filter using k
+        if (-p["kValue"] <= pt2.value) and (pt2.value <= p["kValue"]):
+            pt2.value = 0.00
+            
+        # Lei Yan
+        # 05/28/2009
+        # fix color
+        
+        # pick a color
+        if pt2.value >= 0.7:
+            pt2.color = p["cL6Name"]
+            pt2.style = p["L6style"]
+        elif pt2.value >= 0.5:
+            pt2.color = p["cL5Name"]
+            pt2.style = p["L5style"]
+        elif pt2.value >= 0.0:
+            pt2.color = p["cL4Name"]
+            pt2.style = p["L4style"]
+        elif pt2.value >= -0.5:
+            pt2.color = p["cL3Name"]
+            pt2.style = p["L3style"]
+        elif pt2.value >= -0.7:
+            pt2.color = p["cL2Name"]
+            pt2.style = p["L2style"]
+        else:
+            pt2.color = p["cL1Name"]
+            pt2.style = p["L1style"]
+        
+        # r to Z transform to generate the length
+        # 0 gets transformed to infinity, which we can't
+        # represent here, and 1 gets transformed to 0
+        if p["lock"] == "no":
+            if -0.01 < pt2.value and pt2.value < 0.01:
+                pt2.length = 1000
+            elif pt2.value > 0.99 or pt2.value < -0.99:
+                pt2.length = 0
+            else:
+                pt2.length = pt2.value
+                pt2.length = 0.5 * math.log((1 + pt2.length)/(1 - pt2.length))
+        
+                # invert so higher correlations mean closer edges
+                #pt2.length = abs(p["scale"] * 1/pt2.length)
+                pt2.length = abs(1/pt2.length)
+        else:
+            pt2.length = 2
+            
+
+# tuneParamDict: ParamDict -> Int -> Int -> ParamDict
+# to adjust the parameter dictionary for a first-time run
+# so that the graphing doesn't take so long, especially since
+# small parameter changes can make a big performance difference
+# note: you can pass this function an empty dictionary and
+# get back a good set of default parameters for your
+# particular graph
+def tuneParamDict(p, nodes, edges):
+    newp = copy.deepcopy(p)
+    
+    if nodes > 50:
+        newp["splines"] = "no"
+    else:
+        newp["splines"] = "yes"
+        
+    if edges > 1000:
+        newp["printIslands"] = 0
+    else:
+        newp["printIslands"] = 1
+        
+    if edges > 1000:
+        newp["kValue"] = 0.8
+    elif edges > 500:
+        newp["kValue"] = 0.7
+    elif edges > 250:
+        newp["kValue"] = 0.6
+
+    if nodes > 50:
+        # there's no magic here; this formula
+        # just seems to work
+        dim = 3*math.sqrt(nodes)
+        newp["width"] = round(dim,2)
+        newp["height"] = round(dim,2)
+
+        # the two values below shouldn't change 
+        #        newp["scale"] = round(dim/10.0,2)
+        #        newp["fontsize"] = round(14*newp["scale"],0)
+        
+    else:
+        newp["width"] = 40.0
+        newp["height"] = 40.0
+        
+    return newp
+
+# fixLabel : string -> string
+def fixLabel(lbl):
+    """
+    To split a label with newlines so it looks a bit better
+    Note: we send the graphing program literal '\n' strings and
+    it converts these into newlines
+    """
+    lblparts = lbl.split(" ")
+    newlbl = ""
+    i = 0
+    for part in lblparts:
+        if 10*(i+1) < len(newlbl):
+            i += 1
+            newlbl = newlbl + r"\n" + part
+        else:
+            newlbl = newlbl + " " + part
+    return newlbl
+    #return "\N"
+
+def writeGraphFile(matrix, traits, filename, p):
+    """
+    Expresses the same information as the neato file, only in 
+    eXtensible Graph Markup and Modeling Language (XGMML) so the user can develop his/her
+    own graph in a program such as Cytoscape
+    """
+    inputFile1 = open(filename + "_xgmml_symbol.txt", "w")
+    inputFile2 = open(filename + "_xgmml_name.txt", "w")
+    inputFile3 = open(filename + "_plain_symbol.txt", "w")
+    inputFile4 = open(filename + "_plain_name.txt", "w")
+        
+    inputFile1.write("<graph directed=\"1\" label=\"Network Graph\">\n")
+    inputFile2.write("<graph directed=\"1\" label=\"Network Graph\">\n")
+    
+    #Write out nodes
+    traitEdges = []
+    for i in range(0, len(traits)):
+        traitEdges.append(0)
+    
+    for i in range(0, len(traits)):
+            
+        labelName = traits[i].symbol
+        inputFile1.write("\t<node id=\"%s\" label=\"%s\"></node>\n" % (i, labelName))
+    
+    for i in range(0, len(traits)):
+        
+        labelName = traits[i].name
+        inputFile2.write("\t<node id=\"%s\" label=\"%s\"></node>\n" % (i, labelName))
+            
+    #Write out edges
+    for point in matrix:
+
+        traitEdges[point.i] = 1
+        traitEdges[point.j] = 1
+        if p["edges"] == "complex":
+            _traitValue = "%.3f" % point.value
+            inputFile1.write("\t<edge source=\"%s\" target=\"%s\" label=\"%s\"></edge>\n"
+                             % (point.i,
+                                point.j, 
+                                _traitValue))
+            inputFile2.write("\t<edge source=\"%s\" target=\"%s\" label=\"%s\"></edge>\n"
+                             % (point.i,
+                                point.j, 
+                                _traitValue))
+    
+    inputFile1.write("</graph>")
+    inputFile2.write("</graph>")
+            
+    for edge in matrix:
+        inputFile3.write("%s\t%s\t%s\n" % (traits[edge.i].symbol, edge.value, traits[edge.j].symbol))    
+    
+
+    for edge in matrix:
+        inputFile4.write("%s\t%s\t%s\n" % (traits[edge.i].name, edge.value, traits[edge.j].name))         
+                
+    inputFile1.close()
+    inputFile2.close()
+    inputFile3.close()
+    inputFile4.close()
+    
+    return (os.path.split(filename))[1]
+
+# writeNeatoFile : DataMatrix -> arrayof Traits -> String -> ParamDict -> String
+def writeNeatoFile(matrix, traits, filename, GeneIdArray, p):
+    """
+    Given input data, to write a valid input file for neato, optionally
+    writing entries for nodes that have no edges.
+    
+    NOTE: There is a big difference between removing an edge and zeroing
+    its value. Because writeNeatoFile is edge-driven, zeroing an edge's value
+    will still result in its node being written.
+    """
+    inputFile = open(filename, "w")
+    
+    """
+    This file (inputFile_pdf) is rotated 90 degrees. This is because of a bug in graphviz 
+    that causes pdf output onto a non-landscape layout to often be cut off at the edge
+    of the page. This second filename (which is just the first + "_pdf" is then read
+    in the "visualizePage" class in networkGraph.py and used to generate the postscript
+    file that is converted to pdf.
+    """
+    inputFile_pdf = open(filename + "_pdf", "w")
+    
+    
+    if p["splines"] == "yes":
+        splines = "true"
+    else:
+        splines = "false"
+    
+    # header        
+    inputFile.write('''graph webqtlGraph {
+    overlap="false";
+    start="regular";
+    splines="%s";
+    ratio="auto";
+    fontpath = "%s";
+    node [fontname="%s", fontsize=%s, shape="%s"];
+    edge [fontname="%s", fontsize=%s];
+    ''' % (splines, webqtlConfig.PIDDLE_FONT_PATH,
+           p["nfont"], p["nfontsize"], p["nodeshapeType"],
+           p["cfont"], p["cfontsize"]))
+    
+    inputFile_pdf.write('''graph webqtlGraph {
+    overlap="false";
+    start="regular";
+    splines="%s";
+    rotate="90";
+    center="true";
+    size="11,8.5";
+    margin="0";
+    ratio="fill";
+    fontpath = "%s";
+    node [fontname="%s", fontsize=%s, shape="%s"];
+    edge [fontname="%s", fontsize=%s];
+    ''' % (splines, webqtlConfig.PIDDLE_FONT_PATH,
+           p["nfont"], p["nfontsize"], p["nodeshapeType"],
+           p["cfont"], p["cfontsize"]))
+
+    # traitEdges stores whether a particular trait has edges
+    traitEdges = []
+    for i in range(0, len(traits)):
+        traitEdges.append(0)
+       
+    if p["dispcorr"] == "yes":
+        _dispCorr = 1
+    else:
+        _dispCorr = 0
+    # print edges first while keeping track of nodes
+    for point in matrix:
+        if point.value != 0:
+            traitEdges[point.i] = 1
+            traitEdges[point.j] = 1
+            if p["edges"] == "complex":
+                if _dispCorr:
+                    _traitValue = "%.3f" % point.value
+                else:
+                    _traitValue = ""
+                if p["correlationName"] == "Pearson":
+                    inputFile.write('%s -- %s [len=%s, weight=%s, label=\"%s\", color=\"%s\", style=\"%s\", edgeURL=\"javascript:showCorrelationPlot2(db=\'%s\',ProbeSetID=\'%s\',CellID=\'\',db2=\'%s\',ProbeSetID2=\'%s\',CellID2=\'\',rank=\'%s\');\", edgetooltip="%s"];\n'
+                                    % (point.i,
+                                       point.j, 
+                                       point.length,
+                                       point.length, 
+                                       _traitValue,
+                                       point.color,
+                                       point.style,
+                                       str(traits[point.i].datasetName()),
+                                       str(traits[point.i].nameNoDB()),
+                                       str(traits[point.j].datasetName()),
+                                       str(traits[point.j].nameNoDB()),
+                                       "0",
+    				                   "Pearson Correlation Plot between " + str(traits[point.i].symbol) + " and " + str(traits[point.j].symbol)))
+                elif p["correlationName"] == "Spearman":
+                    inputFile.write('%s -- %s [len=%s, weight=%s, label=\"%s\", color=\"%s\", style=\"%s\", edgeURL=\"javascript:showCorrelationPlot2(db=\'%s\',ProbeSetID=\'%s\',CellID=\'\',db2=\'%s\',ProbeSetID2=\'%s\',CellID2=\'\',rank=\'%s\');\", edgetooltip="%s"];\n'
+                                    % (point.i,
+                                       point.j, 
+                                       point.length,
+                                       point.length, 
+                                       _traitValue,
+                                       point.color,
+                                       point.style,
+                                       str(traits[point.j].datasetName()),
+                                       str(traits[point.j].nameNoDB()),
+                                       str(traits[point.i].datasetName()),
+                                       str(traits[point.i].nameNoDB()),
+                                       "1",
+                                       "Spearman Correlation Plot between " + str(traits[point.i].symbol) + " and " + str(traits[point.j].symbol)))    
+                elif p["correlationName"] == "Tissue":
+                    inputFile.write('%s -- %s [len=%s, weight=%s, label=\"%s\", color=\"%s\", style=\"%s\", edgeURL=\"javascript:showTissueCorrPlot(fmName=\'showDatabase\', X_geneSymbol=\'%s\', Y_geneSymbol=\'%s\', rank=\'0\');\", edgetooltip="%s"];\n'
+                                    % (point.i,
+                                       point.j, 
+                                       point.length,
+                                       point.length, 
+                                       _traitValue,
+                                       point.color,
+                                       point.style,
+                                       str(traits[point.i].symbol),
+                                       str(traits[point.j].symbol),
+                                       "Tissue Correlation Plot between " + str(traits[point.i].symbol) + " and " + str(traits[point.j].symbol)))      
+                else:
+                    inputFile.write('%s -- %s [len=%s, weight=%s, label=\"%s\", color=\"%s\", style=\"%s\", edgeURL=\"javascript:showCorrelationPlot2(db=\'%s\',ProbeSetID=\'%s\',CellID=\'\',db2=\'%s\',ProbeSetID2=\'%s\',CellID2=\'\',rank=\'%s\');\", edgetooltip="%s"];\n'
+                                    % (point.i,
+                                       point.j, 
+                                       point.length,
+                                       point.length, 
+                                       _traitValue,
+                                       point.color,
+                                       point.style,
+                                       str(traits[point.i].datasetName()),
+                                       str(traits[point.i].nameNoDB()),
+                                       str(traits[point.j].datasetName()),
+                                       str(traits[point.j].nameNoDB()),
+                                       "0",
+                                       "Correlation Plot between " + str(traits[point.i].symbol) + " and " + str(traits[point.j].symbol)))         
+                inputFile_pdf.write('%s -- %s [len=%s, weight=%s, label=\"%s\", color=\"%s\", style=\"%s\", edgetooltip="%s"];\n'
+                                % (point.i,
+                                   point.j, 
+                                   point.length,
+                                   point.length, 
+                                   _traitValue,
+                                   point.color,
+                                   point.style,
+                                   "Correlation Plot between " + str(traits[point.i].symbol) + " and " + str(traits[point.j].symbol)))
+					
+            else:
+                inputFile.write('%s -- %s [color="%s", style="%s"];\n'
+                                % (point.i, 
+                                   point.j, 
+                                   point.color,
+                                   point.style))
+                inputFile_pdf.write('%s -- %s [color="%s", style="%s"];\n'
+                                % (point.i, 
+                                   point.j, 
+                                   point.color,
+                                   point.style))
+
+    # now print nodes
+    # the target attribute below is undocumented; I found it by looking
+    # in the neato code
+    for i in range(0, len(traits)):
+        if traitEdges[i] == 1 or p["printIslands"] == 1:
+            _tname = str(traits[i])
+            if _tname.find("Publish") > 0:
+            	plotColor = p["cPubName"]
+            elif _tname.find("Geno") > 0:
+            	plotColor = p["cGenName"]
+            else:
+            	plotColor = p["cMicName"]
+            if p['nodelabel'] == 'yes':
+            	labelName = _tname
+            else:
+            	labelName = traits[i].symbol
+
+            inputFile.write('%s [label="%s", href="javascript:showDatabase2(\'%s\',\'%s\',\'\');", color="%s", style = "filled"];\n'
+                            % (i, labelName, traits[i].datasetName(), traits[i].nameNoDB(), plotColor))# traits[i].color
+            inputFile_pdf.write('%s [label="%s", href="javascript:showDatabase2(\'%s\',\'%s\',\'\');", color="%s", style = "filled"];\n'
+                            % (i, labelName, traits[i].datasetName(), traits[i].nameNoDB(), plotColor))# traits[i].color
+            
+    # footer
+    inputFile.write("}\n")
+    inputFile_pdf.write("]\n")
+    inputFile.close()
+    inputFile_pdf.close()
+
+    # return only the filename portion, omitting the directory
+    return (os.path.split(filename))[1]
+
+# runNeato : string -> string -> string
+def runNeato(filename, extension, format, gType):
+    """
+    to run neato on the dataset in the given filename and produce an image file
+    in the given format whose name we will return. Right now we assume
+    that format is a valid neato output (see graphviz docs) and a valid extension
+    for the source datafile. For example,
+    runNeato('input1', 'png') will produce a file called 'input1.png'
+    by invoking 'neato input1 -Tpng -o input1.png'
+    """
+    # trim extension off of filename before adding output extension
+    if filename.find(".") > 0:
+        filenameBase = filename[:filename.find(".")]
+    else:
+        filenameBase = filename
+        
+    imageFilename = filenameBase + "." + extension
+
+    #choose which algorithm to run depended upon parameter gType
+    #neato: energy based algorithm
+    #circular: nodes given circular structure determined by which nodes are most closely correlated
+    #radial: first node listed (when you search) is center of the graph, all other nodes are in a circular structure around it
+    #fdp: force based algorithm
+
+    if gType == "none":
+    # to keep the output of neato from going to stdout, we open a pipe
+    # and then wait for it to terminate
+    
+        if format in ('gif', 'cmapx', 'ps'):
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/neato", "/usr/local/bin/neato", "-s", "-T", format, webqtlConfig.IMGDIR + filename, "-o", webqtlConfig.IMGDIR + imageFilename)
+    
+        else:
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/neato", "/usr/local/bin/neato", webqtlConfig.IMGDIR + filename, "-T", format, "-o", webqtlConfig.IMGDIR + imageFilename)
+
+        if neatoExit == 0:
+            return imageFilename
+        
+        return imageFilename
+
+
+    elif gType == "neato":
+    # to keep the output of neato from going to stdout, we open a pipe
+    # and then wait for it to terminate
+        if format in ('gif', 'cmapx', 'ps'):
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/neato", "/usr/local/bin/neato", "-s", "-T", format, webqtlConfig.IMGDIR + filename, "-o", webqtlConfig.IMGDIR + imageFilename)
+    
+        else:
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/neato", "/usr/local/bin/neato", webqtlConfig.IMGDIR + filename, "-T", format, "-o", webqtlConfig.IMGDIR + imageFilename)
+
+        if neatoExit == 0:
+            return imageFilename
+        
+        return imageFilename
+
+    elif gType == "circular":
+	
+        if format in ('gif', 'cmapx', 'ps'):
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/circo", "/usr/local/bin/circo", "-s", "-T", format, webqtlConfig.IMGDIR + filename, "-o", webqtlConfig.IMGDIR + imageFilename)
+        
+        else:
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/circo", "/usr/local/bin/circo", webqtlConfig.IMGDIR + filename, "-T", format, "-o", webqtlConfig.IMGDIR + imageFilename)
+
+        if neatoExit == 0:
+            return imageFilename
+        
+        return imageFilename
+
+    elif gType == "radial":
+	
+        if format in ('gif', 'cmapx', 'ps'):
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/twopi", "/usr/local/bin/twopi", "-s", "-T", format, webqtlConfig.IMGDIR + filename, "-o", webqtlConfig.IMGDIR + imageFilename)
+        
+        else:
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/twopi", "/usr/local/bin/twopi", webqtlConfig.IMGDIR + filename, "-T", format, "-o", webqtlConfig.IMGDIR + imageFilename)
+
+        if neatoExit == 0:
+            return imageFilename
+        
+        return imageFilename
+
+    elif gType == "fdp":
+
+        if format in ('gif', 'cmapx', 'ps'):
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/fdp", "/usr/local/bin/fdp", "-s", "-T", format, webqtlConfig.IMGDIR + filename, "-o", webqtlConfig.IMGDIR + imageFilename)
+        
+        else:
+            neatoExit = os.spawnlp(os.P_WAIT, "/usr/local/bin/fdp", "/usr/local/bin/fdp", webqtlConfig.IMGDIR + filename, "-T", format, "-o", webqtlConfig.IMGDIR + imageFilename)
+
+        if neatoExit == 0:
+            return imageFilename
+        
+        return imageFilename
+    
+
+    return imageFilename
+# runPsToPdf: string -> int -> intstring
+# to run Ps2Pdf to convert the given input postscript file to an 8.5 by 11
+# pdf file The width and height should be specified in inches. We assume
+# that the PS files output by GraphViz are 72 dpi.
+def runPsToPdf(psfile, width, height):
+    # we add 1 for padding b/c sometimes a small part of the graph gets
+    # cut off
+    newwidth = int((width + 1) * 720)
+    newheight = int((height + 1) * 720)
+
+    # replace the ps extension with a pdf one
+    pdffile = psfile[:-2] + "pdf"
+
+    os.spawnlp(os.P_WAIT, "ps2pdf", 
+               "-g%sx%s" % (newwidth, newheight),
+               webqtlConfig.IMGDIR + psfile, webqtlConfig.IMGDIR + pdffile)
+
+    return pdffile
+
+# buildParamDict: void -> ParamDict
+# to process and validate CGI arguments,
+# looking up human-readable names where necessary
+# see the comment at the top of the file for valid cgi parameters
+def buildParamDict(fs, sessionfile):
+    params = {}
+       
+    params["inputFile"] = fs.formdata.getvalue("inputFile", "")
+    params["progress"] = fs.formdata.getvalue("progress", "1")
+    params["filename"] = fs.formdata.getvalue("filename", "")
+    params["session"] = sessionfile
+    
+    if type("1") != type(fs.formdata.getvalue("searchResult")):
+        params["searchResult"] = string.join(fs.formdata.getvalue("searchResult"),'\t')
+    else:
+        params["searchResult"] = fs.formdata.getvalue("searchResult")
+        
+    params["riset"] = fs.formdata.getvalue("RISet", "")
+    #if params["filename"] == "":
+    #    raise nGraphException("Required parameter filename missing")
+   
+    #parameter determining whether export button returns an xgmml graph file or plain text file
+    params["exportFormat"] = fs.formdata.getvalue("exportFormat", "xgmml")
+    
+    #parameter determining whether or not traits in the graph file are listed by their symbol or name
+    params["traitType"] = fs.formdata.getvalue("traitType", "symbol")
+   
+    #parameter saying whether or not graph structure should be locked when you redraw the graph
+    params["lock"] = fs.formdata.getvalue("lock", "no")
+    
+    #parameter saying what algorithm should be used to draw the graph
+    params["gType"] = fs.formdata.getvalue("gType", "none")
+
+    params["kValue"] = webqtlUtil.safeFloat(fs.formdata.getvalue("kValue", "0.5"), 0.5)
+    params["whichValue"] = webqtlUtil.safeInt(fs.formdata.getvalue("whichValue","0"),0)
+    
+    # 1 inch = 2.54 cm
+    # 1 cm = 0.3937 inch
+    
+    params["width"] = webqtlUtil.safeFloat(fs.formdata.getvalue("width", "40.0"), 40.0)
+    params["height"] = webqtlUtil.safeFloat(fs.formdata.getvalue("height", "40.0"), 40.0)
+    
+    yesno = ["yes", "no"]
+    
+    params["tune"] = webqtlUtil.safeString(fs.formdata.getvalue("tune", "yes"), yesno, "yes")
+    
+    params["printIslands"] = webqtlUtil.safeInt(fs.formdata.getvalue("printIslands", "1"),1)
+    params["nodeshape"] = webqtlUtil.safeString(fs.formdata.getvalue("nodeshape","yes"), yesno, "yes")
+    params["nodelabel"] = webqtlUtil.safeString(fs.formdata.getvalue("nodelabel","no"), yesno, "no")
+    params["nfont"] = fs.formdata.getvalue("nfont","Arial")
+    params["nfontsize"] = webqtlUtil.safeFloat(fs.formdata.getvalue("nfontsize", "10.0"), 10.0)
+
+    params["splines"] = webqtlUtil.safeString(fs.formdata.getvalue("splines","yes"), yesno, "yes")    
+    params["dispcorr"] = webqtlUtil.safeString(fs.formdata.getvalue("dispcorr","no"), yesno, "no")
+    params["cfont"] = fs.formdata.getvalue("cfont","Arial")
+    params["cfontsize"] = webqtlUtil.safeFloat(fs.formdata.getvalue("cfontsize", "10.0"), 10.0)
+    
+    params["cPubName"] = fs.formdata.getvalue("cPubName","palegreen")
+    params["cMicName"] = fs.formdata.getvalue("cMicName","lightblue")
+    params["cGenName"] = fs.formdata.getvalue("cGenName","lightcoral")
+    
+    params["cPubColor"] = fs.formdata.getvalue("cPubColor","98fb98")
+    params["cMicColor"] = fs.formdata.getvalue("cMicColor","add8e6")
+    params["cGenColor"] = fs.formdata.getvalue("cGenColor","f08080")
+    
+    params["cL1Name"] = fs.formdata.getvalue("cL1Name","blue")
+    params["cL2Name"] = fs.formdata.getvalue("cL2Name","green")
+    params["cL3Name"] = fs.formdata.getvalue("cL3Name","black")
+    params["cL4Name"] = fs.formdata.getvalue("cL4Name","pink")
+    params["cL5Name"] = fs.formdata.getvalue("cL5Name","orange")
+    params["cL6Name"] = fs.formdata.getvalue("cL6Name","red")
+    
+    params["cL1Color"] = fs.formdata.getvalue("cL1Color","0000ff")
+    params["cL2Color"] = fs.formdata.getvalue("cL2Color","00ff00")
+    params["cL3Color"] = fs.formdata.getvalue("cL3Color","000000")
+    params["cL4Color"] = fs.formdata.getvalue("cL4Color","ffc0cb")
+    params["cL5Color"] = fs.formdata.getvalue("cL5Color","ffa500")
+    params["cL6Color"] = fs.formdata.getvalue("cL6Color","ff0000")
+    
+    params["L1style"] = fs.formdata.getvalue("L1style","bold")
+    params["L2style"] = fs.formdata.getvalue("L2style","")
+    params["L3style"] = fs.formdata.getvalue("L3style","dashed")
+    params["L4style"] = fs.formdata.getvalue("L4style","dashed")
+    params["L5style"] = fs.formdata.getvalue("L5style","")
+    params["L6style"] = fs.formdata.getvalue("L6style","bold")
+    
+    if params["splines"] == "yes":
+        params["splineName"] = "curves"
+    else:
+        params["splineName"] = "lines"
+        
+    if params["nodeshape"] == "yes":
+        params["nodeshapeType"] = "box"
+    else:
+        params["nodeshapeType"] = "ellipse"
+        
+    if params["whichValue"] == 0:
+        params["correlationName"] = "Pearson"
+    elif params["whichValue"] == 1:
+        params["correlationName"] = "Spearman"
+    elif params["whichValue"] == 2:
+        params["correlationName"] = "Literature"
+    else:
+        params["correlationName"] = "Tissue"
+
+    # see graphviz::writeNeatoFile to find out what this done
+    params["edges"] = "complex"
+    
+    return params        
+
+def optimalRadialNode(matrix):
+    """
+    Automatically determines the node with the most/strongest correlations with 
+    other nodes. If the user selects "radial" for Graph Type and then "Auto" for the
+    central node then this node is used as the central node. The algorithm is simply a sum of 
+    each node's correlations that fall above the threshold set by the user.
+    """
+    
+    optMatrix = [0]*(len(matrix)+1)
+    
+    for pt in matrix:
+	 if abs(pt.value) > 0.5:
+            optMatrix[pt.i] += abs(pt.value)
+            optMatrix[pt.j] += abs(pt.value)
+    
+    optPoint = 0
+    optCorrTotal = 0
+    
+    j = 0
+    
+    for point in optMatrix:
+        if (float(point) > float(optCorrTotal)):
+            optPoint = j
+            optCorrTotal = point
+        j += 1
+    
+    
+    return optPoint    
+    
+# filterDataMatrix : DataMatrix -> ParamDict -> DataMatrix
+def filterDataMatrix(matrix, p):
+    """
+    To convert a set of input RawPoints to a set of
+    ProcessedPoints and to choose the appropriate
+    correlation coefficent.
+    """
+    newmatrix = []
+    for pt in matrix:
+        pt2 = ProcessedPoint(pt.i, pt.j) # XZ, 09/11/2008: add module name
+        
+        # pick right value
+        if p["whichValue"] == 0:
+            pt2.value = pt.pearson
+        elif p["whichValue"] == 1:
+            pt2.value = pt.spearman
+        elif p["whichValue"] == 2:
+            pt2.value = pt.literature
+        elif p["whichValue"] == 3:
+            pt2.value = pt.tissue
+        else:
+            raise nGraphException("whichValue should be either 0, 1, 2 or 3")
+
+        try:
+            pt2.value = float(pt2.value)
+        except:
+            pt2.value = 0.00
+
+        newmatrix.append(pt2)
+        
+        
+
+    return newmatrix
+   
+def generateSymbolList(traits):
+    """ 
+    Generates a list of trait symbols to be displayed in the central node 
+    selection drop-down menu when plotting a radial graph
+    """
+        
+    traitList = traits
+    
+    symbolList = [None]*len(traitList)
+    
+    i=0
+    for trait in traitList:
+        symbolList[i] = str(trait.symbol)
+        i = i+1
+        
+    symbolListString = "\t".join(symbolList)
+    
+    return symbolListString       
+