예제 #1
0
파일: web.py 프로젝트: yongwangCPH/peat
    def do_search(self, globalop, proteinop, proteins, datasets):
        """Do searches for the various parameters, name, pka etc"""

        import re, urllib
        from PEATDB.PEATTables import PEATTableModel
        from PEATDB.Ekin.Fitting import Fitting
        from PEATDB.Ekin.Web import EkinWeb
        DB = self.DB
        EW = EkinWeb()
        ekincols = DB.ekintypes

        found=[]
        protlist = proteins.split(' ')
        residuelist = residues.split(' ')

        def createPhrase(items, op):
            if op == 'or':
                logicsymbol = '|'
            else:
                logicsymbol = '+'
            itemlist = items.split(' ')
            phrase =''
            c=1
            for i in itemlist:
                if c == len(itemlist):
                    phrase = phrase + i
                else:
                    phrase = phrase + i + logicsymbol
                c=c+1
            return re.compile(phrase, re.IGNORECASE)

        #if there is a protein name entered, get the list of proteins/records to use
        #otherwise use all records to search for the other keys
        names = []
        keywords = {}
        for p in DB.getRecs():
            name = DB[p].name
            names.append((name,p))
            if hasattr(DB[p], 'keywords'):
                keywords[name] = DB[p].keywords
            else:
                keywords[name] = ''
        names.sort()

        #create search expressions
        s_protein = createPhrase(proteins, proteinop)
        s_residue = createPhrase(residues, 'or')
        pkarange = pka.split('-')

        #do search
        for name in names:
            proteinname = name[0]
            protein = name[1]
            if s_protein.search(proteinname) or s_protein.search(keywords[proteinname]):
                found.append(protein)

        if len(found)==0:
            print '<h2>Sorry, no proteins found that match this name. <h2>'
            return
        elif residues == '' and pka == '':
            self.show_DB(selected=found)
            return found

        #now search for the other keys inside selected proteins if needed
        ekinfound={}; foundfits={}
        ignore =['__fit_matches__', '__Exp_Meta_Dat__', '__datatabs_fits__']

        kys = list(DB.getRecs())
        kys.sort()
        if len(found) == 0 or globalop == 'or':
            found = DB.getRecs()

        print '<table id="mytable" cellspacing=0 align=center>'
        '''search recs for residue and pkarange
           and add dataset names to new ekinfound dict'''
        for protein in found:
            for col in DB[protein].keys():
                if nucleus != 'any':
                    if nucleus not in col:
                        continue
                E = DB[protein][col]
                if DB['userfields'].has_key(col):
                    fieldtype=DB['userfields'][col]['field_type']
                else:
                    fieldtype=None
                if fieldtype in ekincols:
                    dk = E.datasets
                    fits = E.__datatabs_fits__
                    for k in dk:
                        meta = E.getMetaData(k)
                        try:
                            thisres = meta['residue']
                        except:
                            thisres = k
                        if thisres == None:
                            thisres = k
                        if residues != '':
                            if s_residue.search(thisres) and not k in ignore:
                                if not ekinfound.has_key(protein+'$'+col):
                                    ekinfound[protein+'$'+col]=[]
                                ekinfound[protein+'$'+col].append(k)

                        if pka != '':
                            foundpka = 0
                            if k in fits.keys():
                                if fits[k] == None:
                                    continue
                                if fits[k].has_key('model'):
                                    model = fits[k]['model']
                                else:
                                    continue
                                if not foundfits.has_key(protein+'$'+col):
                                    foundfits[protein+'$'+col]={}
                                X = Fitting.getFitter(model)
                                pnames = X.names
                                i=0
                                #check if first num is larger, then swap
                                try:
                                    pk1=float(pkarange[0])
                                    pk2=float(pkarange[1])
                                except:
                                    print '<h2> Error: pka values are not valid </h2>'
                                    return
                                if pk1 > pk2:
                                    tmp = pk1
                                    pk1 = pk2
                                    pk2 = tmp

                                #iterate thru parameter names and match any pK fields
                                #this code is not that efficient!
                                for p in pnames:
                                    if 'pK' in p:
                                        pka = fits[k][i]
                                        if pka >= pk1 and pka <= pk2:
                                            foundpka=1
                                    i=i+1
                                #if match is 'ANY', just append dataset if not there already
                                #also for case if no residue value entered
                                if globalop == 'or' or residues == '':
                                    if foundpka == 1:
                                        if not ekinfound.has_key(protein+'$'+col):
                                            ekinfound[protein+'$'+col]=[]
                                        if not k in ekinfound[protein+'$'+col]:
                                            ekinfound[protein+'$'+col].append(k)
                                #if match is 'ALL', need to check dataset already found
                                #and if no pka found, remove it. if both are true keep it
                                elif globalop == 'and':
                                    if foundpka == 0:
                                        if ekinfound.has_key(protein+'$'+col) and k in ekinfound[protein+'$'+col]:
                                            #print 'removing', protein, col
                                            ekinfound[protein+'$'+col].remove(k)

                                foundfits[protein+'$'+col][k]=fits[k]
        #check for empty fields in ekinfound dict and delete them..
        for d in ekinfound.keys():
            if len(ekinfound[d])==0:
                del(ekinfound[d])

        #if no results, just say that and return
        if len(ekinfound)==0:
            print '<h2> Sorry, no records found that match these parameters. </h2>'
            return
        #top display button and options
        print '<form name="resultsform" action="%s/main.cgi" METHOD="POST" ENCTYPE="multipart/form-data">' %self.bindir
        self.write_sessionkey('show_datasets')
        print '<td valign=top align=right colspan=3> <input type=submit value="display selected" name=submit>'
        print '<label><input type=checkbox name="plotoption" value=3>single graph</label>'
        print '<label><input type=checkbox name="normalise" value=1>normalise</label>'
        print '<label><input type=checkbox name="logx" value=1>log-x</label>'
        print '<label><input type=checkbox name="logy" value=1>log-y</label>'
        print '<label><input type=checkbox name="legend" value=1>legend</label>'
        print '<input type=button value="Check All" onClick="checkAll(document.resultsform.residue)">'
        print '<input type=button value="Uncheck All" onClick="uncheckAll(document.resultsform.residue)"></td>'
        print '</tr>'
        #header
        cols=['protein','column','residues']
        for c in cols:
            print '<th>'+c+'</th>'
        print '</tr>'
        ekys = ekinfound.keys()
        ekys.sort()

        r=1
        for k in ekys:
            if r % 2 == 0:
                cls = "spec"
            else:
                cls = ""

            fields = k.split('$')
            protein = fields[0]
            column = fields[1]

            proteinname = DB[protein]['name']
            print '<tr>'
            print '<th class="spec">%s</th> <td> %s </td>' %(proteinname, column)
            print '<td>'
            for residue in ekinfound[k]:
                residuefield = k+"$"+residue
                fithtml = ''
                try:
                    print '<input type=checkbox id="residue" name="residue" value=%s>' %("'"+residuefield+"'")
                except:
                    print 'UnicodeEncodeError'
                    continue

                urlfields = urllib.urlencode({'login':self.user,'project':self.project,
                                           'residue': residuefield,'action': 'show_datasets'})
                print '<a href="/cgi-bin/titration_db/main.cgi?%s" target="_blank">%s</a>'\
                          % (urlfields, residue)

            print '</tr>'
            r=r+1
        print '</form>'
        print '</table>'
        self.footer()

        return