Esempio n. 1
0
    def calculate_correlation(self, values, method):
        """Calculate the correlation value and p value according to the method specified"""

        # ZS: This takes the list of values of the trait our selected trait is being correlated against and removes the values of the samples our trait has no value for
        # There's probably a better way of dealing with this, but I'll have to ask Christian
        updated_raw_values = []
        updated_values = []
        for i in range(len(values)):
            if values[i] != "None":
                updated_raw_values.append(self.raw_values[i])
                updated_values.append(values[i])

        self.raw_values = updated_raw_values
        values = updated_values

        if method == METHOD_SAMPLE_PEARSON or method == METHOD_LIT or method == METHOD_TISSUE_PEARSON:
            corr, nOverlap = webqtlUtil.calCorrelation(self.raw_values, values, len(values))
        else:
            corr, nOverlap = webqtlUtil.calCorrelationRank(self.raw_values, values, len(values))

        self.correlation = corr
        self.overlap = nOverlap

        if self.overlap < 3:
            self.p_value = 1.0
        else:
            # ZS - This is probably the wrong way to deal with this. Correlation values of 1.0 definitely exist (the trait correlated against itself), so zero division needs to br prevented.
            if abs(self.correlation) >= 1.0:
                self.p_value = 0.0
            else:
                ZValue = 0.5 * log((1.0 + self.correlation) / (1.0 - self.correlation))
                ZValue = ZValue * sqrt(self.overlap - 3)
                self.p_value = 2.0 * (1.0 - reaper.normp(abs(ZValue)))
Esempio n. 2
0
    def calculate_correlation(self, values, method):
        """Calculate the correlation value and p value according to the method specified"""

        #ZS: This takes the list of values of the trait our selected trait is being correlated against and removes the values of the samples our trait has no value for
        #There's probably a better way of dealing with this, but I'll have to ask Christian
        updated_raw_values = []
        updated_values = []
        for i in range(len(values)):
            if values[i] != "None":
                updated_raw_values.append(self.raw_values[i])
                updated_values.append(values[i])

        self.raw_values = updated_raw_values
        values = updated_values

        if method == METHOD_SAMPLE_PEARSON or method == METHOD_LIT or method == METHOD_TISSUE_PEARSON:
            corr, nOverlap = webqtlUtil.calCorrelation(self.raw_values, values, len(values))
        else:
            corr, nOverlap = webqtlUtil.calCorrelationRank(self.raw_values, values, len(values))

        self.correlation = corr
        self.overlap = nOverlap

        if self.overlap < 3:
            self.p_value = 1.0
        else:
            #ZS - This is probably the wrong way to deal with this. Correlation values of 1.0 definitely exist (the trait correlated against itself), so zero division needs to br prevented.
            if abs(self.correlation) >= 1.0:
                self.p_value = 0.0
            else:
                ZValue = 0.5*log((1.0+self.correlation)/(1.0-self.correlation))
                ZValue = ZValue*sqrt(self.overlap-3)
                self.p_value = 2.0*(1.0 - reaper.normp(abs(ZValue)))
Esempio n. 3
0
       	def buildCanvas(self, colorScheme='', targetDescriptionChecked='', clusterChecked='', sessionfile='', genotype=None, strainlist=None, ppolar=None, mpolar=None, traitList=None, traitDataList=None, userPrivilege=None, userName=None):
                labelFont = pid.Font(ttf="tahoma",size=14,bold=0)
                topHeight = 0
       	       	NNN = len(traitList)
       	       	#XZ: It's necessory to define canvas here
                canvas = pid.PILCanvas(size=(80+NNN*20,880))
                names = map(webqtlTrait.displayName, traitList)
                #XZ, 7/29/2009: create trait display and find max strWidth
                strWidth = 0
                for j in range(len(names)):
                        thisTrait = traitList[j]
                        if targetDescriptionChecked:
                            if thisTrait.db.type == 'ProbeSet':
                                if thisTrait.probe_target_description:
                                        names[j] += ' [%s at Chr %s @ %2.3fMB, %s]' % (thisTrait.symbol, thisTrait.chr, thisTrait.mb, thisTrait.probe_target_description)
                                else:
                                        names[j] += ' [%s at Chr %s @ %2.3fMB]' % (thisTrait.symbol, thisTrait.chr, thisTrait.mb)
                            elif thisTrait.db.type == 'Geno':
                                names[j] += ' [Chr %s @ %2.3fMB]' % (thisTrait.chr, thisTrait.mb)
                            elif thisTrait.db.type == 'Publish':
                                if thisTrait.confidential:
                                    if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=userPrivilege, userName=userName, authorized_users=thisTrait.authorized_users):
                                        if thisTrait.post_publication_abbreviation:
                                            names[j] += ' [%s]' % (thisTrait.post_publication_abbreviation)
                                    else:
                                        if thisTrait.pre_publication_abbreviation:
                                            names[j] += ' [%s]' % (thisTrait.pre_publication_abbreviation)
                                else:
                                    if thisTrait.post_publication_abbreviation:
                                        names[j] += ' [%s]' % (thisTrait.post_publication_abbreviation)
                            else:
                                pass

                        i = canvas.stringWidth(names[j], font=labelFont)
                        if i > strWidth:
                                strWidth = i

                width = NNN*20
                xoffset = 40
                yoffset = 40
                cellHeight = 3
                nLoci = reduce(lambda x,y: x+y, map(lambda x: len(x),genotype),0)

                if nLoci > 2000:
                        cellHeight = 1
                elif nLoci > 1000:
                        cellHeight = 2
                elif nLoci < 200:
                        cellHeight = 10
                else:
                        pass

                pos = range(NNN)
                neworder = []
                BWs = Plot.BWSpectrum()
                colors100 = Plot.colorSpectrum()
                colors = Plot.colorSpectrum(130)
                finecolors = Plot.colorSpectrum(250)
                colors100.reverse()
                colors.reverse()
                finecolors.reverse()

                scaleFont=pid.Font(ttf="tahoma",size=10,bold=0)
				
                if not clusterChecked: #XZ: this part is for original order
                        for i in range(len(names)):
                                neworder.append((xoffset+20*(i+1), i))

                        canvas = pid.PILCanvas(size=(80+NNN*20+240,80+ topHeight +5+5+strWidth+nLoci*cellHeight+80+20*cellHeight))

                        self.drawTraitNameBottom(canvas,names,yoffset,neworder,strWidth,topHeight,labelFont)
                else: #XZ: this part is to cluster traits
                        topHeight = 400
                        canvas = pid.PILCanvas(size=(80+NNN*20+240,80+ topHeight +5+5+strWidth+nLoci*cellHeight+80+20*cellHeight))

                        corArray = [([0] * (NNN))[:] for i in range(NNN)]

                        nnCorr = len(strainlist)

                        #XZ, 08/04/2009: I commented out pearsonArray, spearmanArray
                        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)
                                            if (1-corr) < 0:
                                                    distance = 0.0
                                            else:
                                                    distance = 1-corr
                                            corArray[i][j] = distance
                                            corArray[j][i] = distance
                                    elif j == i:
                                            corArray[i][j] = 0.0
                                    else:
                                            pass

                        #XZ, 7/29/2009: The parameter d has info of cluster (group member and distance). The format of d is tricky. Print it out to see it's format.
                        d = slink.slink(corArray)

                        #XZ, 7/29/2009: Attention: The 'neworder' is changed by the 'draw' function
                        #XZ, 7/30/2009: Only toppos[1][0] and top[1][1] are used later. Then what toppos[0] is used for? 
                        toppos = self.draw(canvas,names,d,xoffset,yoffset,neworder,topHeight)
                        self.drawTraitNameTop(canvas,names,yoffset,neworder,strWidth,topHeight,labelFont)

                        #XZ, 7/29/2009: draw the top vertical line
                        canvas.drawLine(toppos[1][0],toppos[1][1],toppos[1][0],yoffset)

                        #XZ: draw string 'distance = 1-r'
                        canvas.drawString('distance = 1-r',neworder[-1][0] + 50, topHeight*3/4,font=labelFont,angle=90)

                        #draw Scale
                        scaleFont=pid.Font(ttf="tahoma",size=10,bold=0)
                        x = neworder[-1][0]
                        canvas.drawLine(x+5, topHeight+yoffset, x+5, yoffset, color=pid.black)
                        y = 0
                        while y <=2:
                                canvas.drawLine(x+5, topHeight*y/2.0+yoffset, x+10, topHeight*y/2.0+yoffset)
                                canvas.drawString('%2.1f' % (2-y), x+12, topHeight*y/2.0+yoffset, font=scaleFont)
                                y += 0.5


                chrname = 0
                chrnameFont=pid.Font(ttf="tahoma",size=24,bold=0)
                Ncol = 0

                nearestMarkers = self.getNearestMarker(traitList, genotype)

                # import cPickle
                if sessionfile:
                        fp = open(os.path.join(webqtlConfig.TMPDIR, sessionfile + '.session'), 'rb')
                        permData = cPickle.load(fp)
                        fp.close()
                else:
                        permData = {}

                areas = []
				#XZ, 7/31/2009: This for loop is to generate the heatmap
                #XZ: draw trait by trait instead of marker by marker
                for order in neworder:
                        #startHeight = 40+400+5+5+strWidth
                        startHeight = topHeight + 40+5+5+strWidth
                        startWidth = order[0]-5
                        if Ncol and Ncol % 5 == 0:
                                drawStartPixel = 8
                        else:
                                drawStartPixel = 9

                        tempVal = traitDataList[order[1]]
                        _vals = []
                        _strains = [] 
                        for i in range(len(strainlist)):
                                if tempVal[i] != None:
                                        _strains.append(strainlist[i])
                                        _vals.append(tempVal[i])

                        qtlresult = genotype.regression(strains = _strains, trait = _vals)

                        if sessionfile:
                                LRSArray = permData[str(traitList[order[1]])]
                        else:
                                LRSArray = genotype.permutation(strains = _strains, trait = _vals, nperm = 1000)
                                permData[str(traitList[order[1]])] = LRSArray

                        sugLRS = LRSArray[369]
                        sigLRS = LRSArray[949]
                        prechr = 0
                        chrstart = 0
                        nearest = nearestMarkers[order[1]]
                        midpoint = []

                        for item in qtlresult:
                                if item.lrs > webqtlConfig.MAXLRS:
                                        adjustlrs = webqtlConfig.MAXLRS
                                else:
                                        adjustlrs = item.lrs

                                if item.locus.chr != prechr:
                                        if prechr:
                                                canvas.drawRect(startWidth-drawStartPixel, startHeight, startWidth+10, startHeight+3,edgeColor=pid.white, edgeWidth=0, fillColor=pid.white)
                                                startHeight+= 3
                                                if not chrname:
                                                        canvas.drawString(prechr,xoffset-20,(chrstart+startHeight)/2,font = chrnameFont,color=pid.dimgray)
                                        prechr = item.locus.chr
                                        chrstart = startHeight
                                if colorScheme == '0':
                                        if adjustlrs <= sugLRS:
                                                colorIndex = int(65*adjustlrs/sugLRS)
                                        else:
                                                colorIndex = int(65 + 35*(adjustlrs-sugLRS)/(sigLRS-sugLRS))
                                        if colorIndex > 99:
                                                colorIndex = 99
                                        colorIndex = colors100[colorIndex]
                                elif colorScheme == '1':
                                        sugLRS = LRSArray[369]/2.0
                                        if adjustlrs <= sugLRS:
                                                colorIndex = BWs[20+int(50*adjustlrs/sugLRS)]
                                        else:
                                                if item.additive > 0:
                                                        colorIndex = int(80 + 50*(adjustlrs-sugLRS)/(sigLRS-sugLRS))
                                                else:
                                                        colorIndex = int(50 - 50*(adjustlrs-sugLRS)/(sigLRS-sugLRS))
                                                if colorIndex > 129:
                                                        colorIndex = 129
                                                if colorIndex < 0:
                                                        colorIndex = 0
                                                colorIndex = colors[colorIndex]
                                elif colorScheme == '2':
                                        if item.additive > 0:
                                                colorIndex = int(150 + 100*(adjustlrs/sigLRS))
                                        else:
                                                colorIndex = int(100 - 100*(adjustlrs/sigLRS))
                                        if colorIndex > 249:
                                                colorIndex = 249
                                        if colorIndex < 0:
                                                        colorIndex = 0
                                        colorIndex = finecolors[colorIndex]
                                else:
                                        colorIndex = pid.white

                                if startHeight > 1:
                                        canvas.drawRect(startWidth-drawStartPixel, startHeight, startWidth+10, startHeight+cellHeight,edgeColor=colorIndex, edgeWidth=0, fillColor=colorIndex)
                                else:
                                        canvas.drawLine(startWidth-drawStartPixel, startHeight, startWidth+10, startHeight, Color=colorIndex)

                                if item.locus.name == nearest:
                                        midpoint = [startWidth,startHeight-5]
                                startHeight+=cellHeight

                        #XZ, map link to trait name and band
                        COORDS = "%d,%d,%d,%d" %(startWidth-drawStartPixel,topHeight+40,startWidth+10,startHeight)
                        HREF = "javascript:showDatabase2('%s','%s','%s');" % (traitList[order[1]].db.name, traitList[order[1]].name, traitList[order[1]].cellid)
                        area = (COORDS, HREF, '%s' % names[order[1]])
                        areas.append(area)

                        if midpoint:
                                traitPixel = ((midpoint[0],midpoint[1]),(midpoint[0]-6,midpoint[1]+12),(midpoint[0]+6,midpoint[1]+12))
                                canvas.drawPolygon(traitPixel,edgeColor=pid.black,fillColor=pid.orange,closed=1)

                        if not chrname:
                                canvas.drawString(prechr,xoffset-20,(chrstart+startHeight)/2,font = chrnameFont,color=pid.dimgray)
                        chrname = 1
                        Ncol += 1


                #draw Spectrum
                startSpect = neworder[-1][0] + 30
                startHeight = topHeight + 40+5+5+strWidth

                if colorScheme == '0':
                        for i in range(100):
                                canvas.drawLine(startSpect+i,startHeight+20,startSpect+i,startHeight+40,color=colors100[i])
                        scaleFont=pid.Font(ttf="tahoma",size=10,bold=0)
                        canvas.drawLine(startSpect,startHeight+45,startSpect,startHeight+39,color=pid.black)
                        canvas.drawString('LRS = 0',startSpect,startHeight+55,font=scaleFont)
                        canvas.drawLine(startSpect+64,startHeight+45,startSpect+64,startHeight+39,color=pid.black)
                        canvas.drawString('Suggestive LRS',startSpect+64,startHeight+55,font=scaleFont)
                        canvas.drawLine(startSpect+99,startHeight+45,startSpect+99,startHeight+39,color=pid.black)
                        canvas.drawString('Significant LRS',startSpect+105,startHeight+40,font=scaleFont)
                elif colorScheme == '1':
                        for i in range(50):
                                canvas.drawLine(startSpect+i,startHeight,startSpect+i,startHeight+40,color=BWs[20+i])
                        for i in range(50,100):
                                canvas.drawLine(startSpect+i,startHeight,startSpect+i,startHeight+20,color=colors[100-i])
                                canvas.drawLine(startSpect+i,startHeight+20,startSpect+i,startHeight+40,color=colors[30+i])

                        canvas.drawLine(startSpect,startHeight+45,startSpect,startHeight+39,color=pid.black)
                        canvas.drawString('LRS = 0',startSpect,startHeight+60,font=scaleFont)
                        canvas.drawLine(startSpect+50,startHeight+45,startSpect+50,startHeight+39,color=pid.black)
                        canvas.drawString('0.5*Suggestive LRS',startSpect+50,startHeight+ 60,font=scaleFont)
                        canvas.drawLine(startSpect+99,startHeight+45,startSpect+99,startHeight+39,color=pid.black)
                        canvas.drawString('Significant LRS',startSpect+105,startHeight+50,font=scaleFont)
                        textFont=pid.Font(ttf="verdana",size=18,bold=0)
                        canvas.drawString('%s +' % ppolar,startSpect+120,startHeight+ 35,font=textFont,color=pid.red)
                        canvas.drawString('%s +' % mpolar,startSpect+120,startHeight+ 15,font=textFont,color=pid.blue)
                elif colorScheme == '2':
                        for i in range(100):
                                canvas.drawLine(startSpect+i,startHeight,startSpect+i,startHeight+20,color=finecolors[100-i])
                                canvas.drawLine(startSpect+i,startHeight+20,startSpect+i,startHeight+40,color=finecolors[150+i])

                        canvas.drawLine(startSpect,startHeight+45,startSpect,startHeight+39,color=pid.black)
                        canvas.drawString('LRS = 0',startSpect,startHeight+60,font=scaleFont)
                        canvas.drawLine(startSpect+99,startHeight+45,startSpect+99,startHeight+39,color=pid.black)
                        canvas.drawString('Significant LRS',startSpect+105,startHeight+50,font=scaleFont)
                        textFont=pid.Font(ttf="verdana",size=18,bold=0)
                        canvas.drawString('%s +' % ppolar,startSpect+120,startHeight+ 35,font=textFont,color=pid.red)
                        canvas.drawString('%s +' % mpolar,startSpect+120,startHeight+ 15,font=textFont,color=pid.blue)
						
                filename= webqtlUtil.genRandStr("Heatmap_")
                canvas.save(webqtlConfig.IMGDIR+filename, format='png')
                if not sessionfile:
                        sessionfile = webqtlUtil.generate_session()
                        webqtlUtil.dump_session(permData, os.path.join(webqtlConfig.TMPDIR, sessionfile +'.session'))
                self.filename=filename
                self.areas=areas
                self.sessionfile=sessionfile
    def __init__(self,fd,InputData=None):

        templatePage.__init__(self, fd)
        self.dict['title'] = 'Correlation Matrix'

        if not self.openMysql():
            return
            
        if not fd.genotype:
            fd.readGenotype()
            fd.strainlist = fd.f1list + fd.strainlist
            
        #self.searchResult = fd.formdata.getvalue('searchResult')
        self.oldSearchResult = fd.formdata.getvalue('oldSearchResult')
        
        if self.oldSearchResult:
            try:
                self.searchResult = fd.formdata.getvalue('oldSearchResult')
            except:
            	self.searchResult = fd.formdata.getvalue('searchResult')
        
        else:
        	self.searchResult = fd.formdata.getvalue('searchResult')
        
        if not self.searchResult:
            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
        if type("1") == type(self.searchResult):
            self.searchResult = [self.searchResult]
        
        if self.searchResult:
            #testvals,names,dbInfos = self.getAllSearchResult(fd,self.searchResult)
            if len(self.searchResult) > 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:
                    if thisTrait.symbol:
                        abbreviation = thisTrait.symbol
                    else:
                        abbreviation = ''
                    _shortName = 'Symbol: %s ' % thisTrait.symbol
                    if thisTrait.symbol:
                        _verboseName = thisTrait.symbol
                    else:
                        _verboseName = ''
                    _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 &nbsp;&nbsp;&nbsp; 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 = """
                <SCRIPT language=JavaScript>
                var allCorrelations = %s;
                </SCRIPT>

            """
            exportScript = exportScript % str(corArray)
            self.dict['js1'] = exportScript+'<SCRIPT SRC="/javascript/correlationMatrix.js"></SCRIPT><BR>'
            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':
		if False:
		   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 __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 not self.searchResult:
                        templatePage.__init__(self, fd)
                        heading = 'QTL Heatmap'
                        detail = ['You need to select at least two traits in order to generate correlation matrix.']
                        self.error(heading=heading,detail=detail)
                        return
                if type("1") == type(self.searchResult):
                        self.searchResult = string.split(self.searchResult,'\t')


                if self.searchResult:
                        if len(self.searchResult) > webqtlConfig.MAXCORR:
                                heading = 'QTL Heatmap'
                                detail = ['In order to display the QTL heat map properly, do not select more than %d traits for analysis.' % webqtlConfig.MAXCORR]
                                self.error(heading=heading,detail=detail)
                                return

                        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 = 'QTL Heatmap'
                        detail = [HT.Font('Error : ',color='red'),HT.Font('Error occurs while retrieving data from database.',color='black')]
                        self.error(heading=heading,detail=detail)
                        return

                self.colorScheme = fd.formdata.getvalue('colorScheme')
                if not self.colorScheme:
                        self.colorScheme = '1'

                self.dict['title'] = 'QTL heatmap'

                NNN = len(traitList)

                if NNN == 0:
                        heading = "QTL Heatmap"
                        detail = ['No trait was selected for %s data set. No QTL heatmap was generated.' % fd.RISet]
                        self.error(heading=heading,detail=detail)
                        return
                elif NNN < 2:
                        templatePage.__init__(self, fd)
                        heading = 'QTL Heatmap'
                        detail = ['You need to select at least two traits in order to generate QTL heatmap.']
                        self.error(heading=heading,detail=detail)
                        return
                else:
                        #XZ: It's necessory to define canvas here
                        canvas = pid.PILCanvas(size=(80+NNN*20,880))

                        names = map(webqtlTrait.displayName, traitList)

                        self.targetDescriptionChecked = fd.formdata.getvalue('targetDescriptionCheck', '')

                        #XZ, 7/29/2009: create trait display and find max strWidth
                        strWidth = 0
                        for j in range(len(names)):
                                thisTrait = traitList[j]

                                if self.targetDescriptionChecked:
                                    if thisTrait.db.type == 'ProbeSet':
                                        if thisTrait.probe_target_description:
                                                names[j] += ' [%s at Chr %s @ %2.3fMB, %s]' % (thisTrait.symbol, thisTrait.chr, thisTrait.mb, thisTrait.probe_target_description)
                                        else:
                                                names[j] += ' [%s at Chr %s @ %2.3fMB]' % (thisTrait.symbol, thisTrait.chr, thisTrait.mb)
                                    elif thisTrait.db.type == 'Geno':
                                        names[j] += ' [Chr %s @ %2.3fMB]' % (thisTrait.chr, thisTrait.mb)
                                    elif thisTrait.db.type == 'Publish':
                                        if thisTrait.abbreviation:
                                            names[j] += ' [%s]' % (thisTrait.abbreviation)
                                        else:
                                            pass
                                    else:
                                        pass

                                i = canvas.stringWidth(names[j],font=self.labelFont)
                                if i > strWidth:
                                        strWidth = i

                        width = NNN*20
                        xoffset = 40
                        yoffset = 40
                        cellHeight = 3
                        nLoci = reduce(lambda x,y: x+y, map(lambda x: len(x),fd.genotype),0)

                        if nLoci > 2000:
                                cellHeight = 1
                        elif nLoci > 1000:
                                cellHeight = 2
                        elif nLoci < 200:
                                cellHeight = 10
                        else:
                                pass

                        pos = range(NNN)
                        neworder = []
                        BWs = Plot.BWSpectrum()
                        colors100 = Plot.colorSpectrum()
                        colors = Plot.colorSpectrum(130)
                        finecolors = Plot.colorSpectrum(250)
                        colors100.reverse()
                        colors.reverse()
                        finecolors.reverse()

                        scaleFont=pid.Font(ttf="tahoma",size=10,bold=0)

                        self.clusterChecked = fd.formdata.getvalue('clusterCheck', '')


                        if not self.clusterChecked: #XZ: this part is for original order
                                for i in range(len(names)):
                                        neworder.append((xoffset+20*(i+1), i))

                                canvas = pid.PILCanvas(size=(80+NNN*20+240,80+ self.topHeight +5+5+strWidth+nLoci*cellHeight+80+20*cellHeight))

                                self.drawTraitNameBottom(canvas,names,yoffset,neworder,strWidth)
                        else: #XZ: this part is to cluster traits
                                self.topHeight = 400
                                canvas = pid.PILCanvas(size=(80+NNN*20+240,80+ self.topHeight +5+5+strWidth+nLoci*cellHeight+80+20*cellHeight))

                                corArray = [([0] * (NNN))[:] for i in range(NNN)]

                                nnCorr = len(fd.strainlist)

                                #XZ, 08/04/2009: I commented out pearsonArray, spearmanArray
                                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)
                                                    if (1-corr) < 0:
                                                            distance = 0.0
                                                    else:
                                                            distance = 1-corr
                                                    corArray[i][j] = distance
                                                    corArray[j][i] = distance
                                            elif j == i:
                                                    corArray[i][j] = 0.0
                                            else:
                                                    pass

                                #XZ, 7/29/2009: The parameter d has info of cluster (group member and distance). The format of d is tricky. Print it out to see it's format.
                                d = slink.slink(corArray)

                                #XZ, 7/29/2009: Attention: The 'neworder' is changed by the 'draw' function
                                #XZ, 7/30/2009: Only toppos[1][0] and top[1][1] are used later. Then what toppos[0] is used for? 
                                toppos = self.draw(canvas,names,d,xoffset,yoffset,neworder)
                                self.drawTraitNameTop(canvas,names,yoffset,neworder,strWidth)

                                #XZ, 7/29/2009: draw the top vertical line
                                canvas.drawLine(toppos[1][0],toppos[1][1],toppos[1][0],yoffset)

                                #XZ: draw string 'distance = 1-r'
                                canvas.drawString('distance = 1-r',neworder[-1][0] + 50, self.topHeight*3/4,font=self.labelFont,angle=90)

                                #draw Scale
                                scaleFont=pid.Font(ttf="tahoma",size=10,bold=0)
                                x = neworder[-1][0]
                                canvas.drawLine(x+5, self.topHeight+yoffset, x+5, yoffset, color=pid.black)
                                y = 0
                                while y <=2:
                                        canvas.drawLine(x+5, self.topHeight*y/2.0+yoffset, x+10, self.topHeight*y/2.0+yoffset)
                                        canvas.drawString('%2.1f' % (2-y), x+12, self.topHeight*y/2.0+yoffset, font=scaleFont)
                                        y += 0.5


                        chrname = 0
                        chrnameFont=pid.Font(ttf="tahoma",size=24,bold=0)
                        Ncol = 0

                        gifmap = HT.Map(name='traitMap')

                        nearestMarkers = self.getNearestMarker(traitList, fd.genotype)

                        # import cPickle
                        sessionfile = fd.formdata.getvalue("session")

                        if sessionfile:
                                fp = open(os.path.join(webqtlConfig.TMPDIR, sessionfile + '.session'), 'rb')
                                permData = cPickle.load(fp)
                                fp.close()
                        else:
                                permData = {}

                        #XZ, 7/31/2009: This for loop is to generate the heatmap
                        #XZ: draw trait by trait instead of marker by marker
                        for order in neworder:
                                #startHeight = 40+400+5+5+strWidth
                                startHeight = self.topHeight + 40+5+5+strWidth
                                startWidth = order[0]-5
                                if Ncol and Ncol % 5 == 0:
                                        drawStartPixel = 8
                                else:
                                        drawStartPixel = 9

                                tempVal = traitDataList[order[1]]
                                _vals = []
                                _strains = [] 
                                for i in range(len(fd.strainlist)):
                                        if tempVal[i] != None:
                                                _strains.append(fd.strainlist[i])
                                                _vals.append(tempVal[i])

                                qtlresult = fd.genotype.regression(strains = _strains, trait = _vals)

                                if sessionfile:
                                        LRSArray = permData[str(traitList[order[1]])]
                                else:
                                        LRSArray = fd.genotype.permutation(strains = _strains, trait = _vals, nperm = 1000)
                                        permData[str(traitList[order[1]])] = LRSArray

                                sugLRS = LRSArray[369]
                                sigLRS = LRSArray[949]
                                prechr = 0
                                chrstart = 0
                                nearest = nearestMarkers[order[1]]
                                midpoint = []

                                for item in qtlresult:
                                        if item.lrs > webqtlConfig.MAXLRS:
                                                adjustlrs = webqtlConfig.MAXLRS
                                        else:
                                                adjustlrs = item.lrs

                                        if item.locus.chr != prechr:
                                                if prechr:
                                                        canvas.drawRect(startWidth-drawStartPixel, startHeight, startWidth+10, startHeight+3,edgeColor=pid.white, edgeWidth=0, fillColor=pid.white)
                                                        startHeight+= 3
                                                        if not chrname:
                                                                canvas.drawString(prechr,xoffset-20,(chrstart+startHeight)/2,font = chrnameFont,color=pid.dimgray)
                                                prechr = item.locus.chr
                                                chrstart = startHeight
                                        if self.colorScheme == '0':
                                                if adjustlrs <= sugLRS:
                                                        colorIndex = int(65*adjustlrs/sugLRS)
                                                else:
                                                        colorIndex = int(65 + 35*(adjustlrs-sugLRS)/(sigLRS-sugLRS))
                                                if colorIndex > 99:
                                                        colorIndex = 99
                                                colorIndex = colors100[colorIndex]
                                        elif self.colorScheme == '1':
                                                sugLRS = LRSArray[369]/2.0
                                                if adjustlrs <= sugLRS:
                                                        colorIndex = BWs[20+int(50*adjustlrs/sugLRS)]
                                                else:
                                                        if item.additive > 0:
                                                                colorIndex = int(80 + 50*(adjustlrs-sugLRS)/(sigLRS-sugLRS))
                                                        else:
                                                                colorIndex = int(50 - 50*(adjustlrs-sugLRS)/(sigLRS-sugLRS))
                                                        if colorIndex > 129:
                                                                colorIndex = 129
                                                        if colorIndex < 0:
                                                                colorIndex = 0
                                                        colorIndex = colors[colorIndex]
                                        elif self.colorScheme == '2':
                                                if item.additive > 0:
                                                        colorIndex = int(150 + 100*(adjustlrs/sigLRS))
                                                else:
                                                        colorIndex = int(100 - 100*(adjustlrs/sigLRS))
                                                if colorIndex > 249:
                                                        colorIndex = 249
                                                if colorIndex < 0:
                                                                colorIndex = 0
                                                colorIndex = finecolors[colorIndex]
                                        else:
                                                colorIndex = pid.white

                                        if startHeight > 1:
                                                canvas.drawRect(startWidth-drawStartPixel, startHeight, startWidth+10, startHeight+cellHeight,edgeColor=colorIndex, edgeWidth=0, fillColor=colorIndex)
                                        else:
                                                canvas.drawLine(startWidth-drawStartPixel, startHeight, startWidth+10, startHeight, Color=colorIndex)

                                        if item.locus.name == nearest:
                                                midpoint = [startWidth,startHeight-5]
                                        startHeight+=cellHeight

                                #XZ, map link to trait name and band
                                COORDS = "%d,%d,%d,%d" %(startWidth-drawStartPixel,self.topHeight+40,startWidth+10,startHeight)
                                HREF = "javascript:showDatabase2('%s','%s','%s');" % (traitList[order[1]].db.name, traitList[order[1]].name, traitList[order[1]].cellid)
                                Areas = HT.Area(shape='rect',coords=COORDS,href=HREF, title='%s' % names[order[1]])
                                gifmap.areas.append(Areas)

                                if midpoint:
                                        traitPixel = ((midpoint[0],midpoint[1]),(midpoint[0]-6,midpoint[1]+12),(midpoint[0]+6,midpoint[1]+12))
                                        canvas.drawPolygon(traitPixel,edgeColor=pid.black,fillColor=pid.orange,closed=1)

                                if not chrname:
                                        canvas.drawString(prechr,xoffset-20,(chrstart+startHeight)/2,font = chrnameFont,color=pid.dimgray)
                                chrname = 1
                                Ncol += 1


                        #draw Spectrum
                        startSpect = neworder[-1][0] + 30
                        startHeight = self.topHeight + 40+5+5+strWidth

                        if self.colorScheme == '0':
                                for i in range(100):
                                        canvas.drawLine(startSpect+i,startHeight+20,startSpect+i,startHeight+40,color=colors100[i])
                                scaleFont=pid.Font(ttf="tahoma",size=10,bold=0)
                                canvas.drawLine(startSpect,startHeight+45,startSpect,startHeight+39,color=pid.black)
                                canvas.drawString('LRS = 0',startSpect,startHeight+55,font=scaleFont)
                                canvas.drawLine(startSpect+64,startHeight+45,startSpect+64,startHeight+39,color=pid.black)
                                canvas.drawString('Suggestive LRS',startSpect+64,startHeight+55,font=scaleFont)
                                canvas.drawLine(startSpect+99,startHeight+45,startSpect+99,startHeight+39,color=pid.black)
                                canvas.drawString('Significant LRS',startSpect+105,startHeight+40,font=scaleFont)
                        elif self.colorScheme == '1':
                                for i in range(50):
                                        canvas.drawLine(startSpect+i,startHeight,startSpect+i,startHeight+40,color=BWs[20+i])
                                for i in range(50,100):
                                        canvas.drawLine(startSpect+i,startHeight,startSpect+i,startHeight+20,color=colors[100-i])
                                        canvas.drawLine(startSpect+i,startHeight+20,startSpect+i,startHeight+40,color=colors[30+i])

                                canvas.drawLine(startSpect,startHeight+45,startSpect,startHeight+39,color=pid.black)
                                canvas.drawString('LRS = 0',startSpect,startHeight+60,font=scaleFont)
                                canvas.drawLine(startSpect+50,startHeight+45,startSpect+50,startHeight+39,color=pid.black)
                                canvas.drawString('0.5*Suggestive LRS',startSpect+50,startHeight+ 60,font=scaleFont)
                                canvas.drawLine(startSpect+99,startHeight+45,startSpect+99,startHeight+39,color=pid.black)
                                canvas.drawString('Significant LRS',startSpect+105,startHeight+50,font=scaleFont)
                                textFont=pid.Font(ttf="verdana",size=18,bold=0)
                                canvas.drawString('%s +' % fd.ppolar,startSpect+120,startHeight+ 35,font=textFont,color=pid.red)
                                canvas.drawString('%s +' % fd.mpolar,startSpect+120,startHeight+ 15,font=textFont,color=pid.blue)
                        elif self.colorScheme == '2':
                                for i in range(100):
                                        canvas.drawLine(startSpect+i,startHeight,startSpect+i,startHeight+20,color=finecolors[100-i])
                                        canvas.drawLine(startSpect+i,startHeight+20,startSpect+i,startHeight+40,color=finecolors[150+i])

                                canvas.drawLine(startSpect,startHeight+45,startSpect,startHeight+39,color=pid.black)
                                canvas.drawString('LRS = 0',startSpect,startHeight+60,font=scaleFont)
                                canvas.drawLine(startSpect+99,startHeight+45,startSpect+99,startHeight+39,color=pid.black)
                                canvas.drawString('Significant LRS',startSpect+105,startHeight+50,font=scaleFont)
                                textFont=pid.Font(ttf="verdana",size=18,bold=0)
                                canvas.drawString('%s +' % fd.ppolar,startSpect+120,startHeight+ 35,font=textFont,color=pid.red)
                                canvas.drawString('%s +' % fd.mpolar,startSpect+120,startHeight+ 15,font=textFont,color=pid.blue)


                        filename= webqtlUtil.genRandStr("Heatmap_")
                        canvas.save(webqtlConfig.IMGDIR+filename, format='png')
                        img2=HT.Image('/image/'+filename+'.png',border=0,usemap='#traitMap')
                        imgUrl = 'Right-click or control-click on the link to download this graph as a <a href="/image/%s.png" class="normalsize" target="_blank">PNG file</a>' % filename

                        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':fd.RISet+"Geno",'CellID':'_','RISet':fd.RISet,'searchResult':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'))

                        heatmap = HT.Input(type='button' ,name='mintmap',value='Redraw QTL Heatmap', onClick="databaseFunc(this.form,'heatmap');",Class="button")
                        spects = {'0':'Single Spectrum','1':'Grey + Blue + Red','2':'Blue + Red'}
                        schemeMenu = HT.Select(name='colorScheme')
                        schemeMenu.append(('Single Spectrum',0))
                        schemeMenu.append(('Grey + Blue + Red',1))
                        schemeMenu.append(('Blue + Red',2))
                        schemeMenu.selected.append(spects[self.colorScheme])

                        clusterCheck= HT.Input(type='checkbox', Class='checkbox', name='clusterCheck',checked=0)
                        targetDescriptionCheck = HT.Input(type='checkbox', Class='checkbox', name='targetDescriptionCheck',checked=0)

                        form.append(gifmap,schemeMenu, heatmap, HT.P(), clusterCheck, '  Cluster traits  ', targetDescriptionCheck, '  Add description', HT.P(),img2, HT.P(), imgUrl)

                        if not sessionfile:
                                filename = webqtlUtil.generate_session()
                                webqtlUtil.dump_session(permData, os.path.join(webqtlConfig.TMPDIR, filename +'.session'))
                                sessionfile=filename

                        form.append(HT.Input(name='session', value=sessionfile, type='hidden'))

                        heatmapHelp = HT.Input(type='button' ,name='heatmapHelpButton',value='Info', onClick="openNewWin('/heatmap.html');",Class="button")

                        heatmapHeading = HT.Paragraph('QTL Heatmap ', heatmapHelp, Class="title")

                        TD_LR = HT.TD(colspan=2,height=200,width="100%",bgColor='#eeeeee')
                        TD_LR.append(heatmapHeading, HT.P(),HT.P(),HT.P(),HT.P(),HT.P(),form)

                        self.dict['body'] = str(TD_LR)
    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']