# $CVSHeader: pal8e/src/Compare_molauto.py,v 1.3 2005/02/15 01:10:24 indraneel Rel $

import os
import string
import re

class Molauto:
    def __init__(self, conf, logger):
        self.conf = conf
        self.logger = logger
        structureID = conf.get('Input', 'structureID')
        molautodir = conf.get('Compare', 'molautodir')
        molautotail = conf.get('Compare', 'molautotail')
        self.fname = molautodir + structureID + molautotail

    def _get_lines(self):
        if not os.path.isfile(self.fname): return []
        fh = file(self.fname)
        lines = fh.readlines()
        fh.close()
        return lines

    def _get_sec_str_lines(self):
        lines = self._get_lines()
        if not lines: return []
        return lines

    def _extract_secstr(self):
        lines = self._get_sec_str_lines()
        secstrdef = {}
        pat = re.compile("(\D?)(\d+)(\D?)")
        for line in lines:
            if line[2:6] == 'coil':
                secstr = 'C'
            elif line[2:8] == 'strand':
                secstr = 'E'
            elif line[2:6] == 'turn':
                secstr = 'T'
            elif line[2:7] == 'helix':
                secstr = 'H'
            else: continue
            vals = line.split()
            start, end = vals[2], vals[4][:-1]
            start, end = pat.match(start).groups(), pat.match(end).groups()
            chain = start[0]
            srid, sicode = int(start[1]), start[2]
            erid, eicode = int(end[1]), end[2]
            if not chain: chain = ' '
            if not sicode: sicode = ' '
            if not eicode: eicode = ' '
            if not secstrdef.has_key(chain):
                secstrdef[chain] = {}
            for rid in range(srid, erid+1):
                if not secstrdef[chain].has_key(rid):
                    v = {' ':secstr, 'A':secstr, 'B':secstr, 'C':secstr}
                    secstrdef[chain][rid] = v
            if not secstrdef[chain][srid].has_key(sicode):
                secstrdef[chain][srid][sicode] = secstr
            if not secstrdef[chain][erid].has_key(eicode):
                secstrdef[chain][erid][eicode] = secstr
        self.secstrdef = secstrdef
            
    def _report(self, peptides):
        total_residues = 0
        total_pssd_H = 0
        total_pssd_E = 0
        total_other_H = 0
        total_other_E = 0
        both_H = 0
        both_E = 0
        only_pssd_H = 0
        only_pssd_E = 0
        only_other_H = 0
        only_other_E = 0
        for peptide in peptides:
            for res in peptide:
                total_residues += 1
                if res.H: total_pssd_H += 1
                if res.E: total_pssd_E += 1
                if res.compare_molauto == 'H': total_other_H += 1
                if res.compare_molauto == 'E': total_other_E += 1
                if res.H and res.compare_molauto == 'H': both_H += 1
                if res.E and res.compare_molauto == 'E': both_E += 1
                if res.H and res.compare_molauto != 'H': only_pssd_H += 1
                if res.E and res.compare_molauto != 'E': only_pssd_E += 1
                if res.compare_molauto == 'H' and not res.H: only_other_H += 1
                if res.compare_molauto == 'E' and not res.E: only_other_E += 1
        line = 'molauto comparison report for '
        line += str(total_residues)+' residues:\n'
        lines = [line]
        lines += ['molauto total_pssd_H '+str(total_pssd_H)+'\n']
        lines += ['molauto total_pssd_E '+str(total_pssd_E)+'\n']
        lines += ['molauto total_other_H '+str(total_other_H)+'\n']
        lines += ['molauto total_other_E '+str(total_other_E)+'\n']
        lines += ['molauto both_H '+str(both_H)+'\n']
        lines += ['molauto both_E '+str(both_E)+'\n']
        lines += ['molauto only_pssd_H '+str(only_pssd_H)+'\n']
        lines += ['molauto only_pssd_E '+str(only_pssd_E)+'\n']
        lines += ['molauto only_other_H '+str(only_other_H)+'\n']
        lines += ['molauto only_other_E '+str(only_other_E)+'\n']
        self.logger.log('compare', lines)

    ## Public Methods
    
    def compare(self, structure, peptides):
        self._extract_secstr()
        for peptide in peptides:
            chain = peptide[0].get_parent().id
            if self.secstrdef.has_key(chain):
                for res in peptide:
                    if self.secstrdef[chain].has_key(res.id[1]):
                        if self.secstrdef[chain][res.id[1]].has_key(res.id[2]):
                            v = self.secstrdef[chain][res.id[1]][res.id[2]]
                            res.compare_molauto = v
        self._report(peptides)
