<commit_before>"""
Provides functionality for interacting with MASCOT data.
"""

import os
from collections import namedtuple
import re
import xml.etree.ElementTree as ET

from pyproteome import paths

MASCOT_NS = {
    "mascot":
        "http://www.matrixscience.com/xmlns/schema/mascot_search_results_2",
}

PeptideQuery = namedtuple(
    "PeptideQuery",
    [
        "gi",
        "protein",
        "query",
        "pep_rank",
        "pep_score",
        "pep_exp_mz",
        "pep_exp_z",
        "pep_seq",
        "pep_var_mods",
        "scan",
    ],
)


def _parse_mascot_2_4_1(root):
    fixed_mods = [
        i.text
        for i in root.findall(
            "mascot:fixed_mods/mascot:modification/mascot:name",
            MASCOT_NS,
        )
    ]
    var_mods = [
        i.text
        for i in root.findall(
            "mascot:variable_mods/mascot:modification/mascot:name",
            MASCOT_NS,
        )
    ]

    scan_used = {}
    index = 0
    out = []

    for hit in root.findall("mascot:hits/mascot:hit", MASCOT_NS):
        accession = hit.find("mascot:protein", MASCOT_NS).get("accession")
        prot_desc = hit.find("mascot:protein/mascot:prot_desc", MASCOT_NS).text

        for peptide in hit.findall("mascot:protein/mascot:peptide", MASCOT_NS):
            query = peptide.get("query")
            rank = peptide.get("rank")
            pep_score = peptide.find("mascot:pep_score", MASCOT_NS).text
            exp_mz = peptide.find("mascot:pep_exp_mz", MASCOT_NS).text
            exp_z = peptide.find("mascot:pep_exp_z", MASCOT_NS).text
            pep_seq = peptide.find("mascot:pep_seq", MASCOT_NS).text

            var_mods = peptide.find("mascot:pep_var_mod", MASCOT_NS).text

            if var_mods:
                var_mods = [
                    re.match(
                        "((\d+) )?(.*)",
                        mod.strip()
                    ).group(2, 3)
                    for mod in var_mods.split(";")
                ]
                var_mods = [
                    (count if count else 1, name)
                    for count, name in var_mods
                ]
            else:
                var_mods = []

            scan = re.search(
                "(scans:|Cmpd_)(\d+)",
                peptide.find("mascot:pep_scan_title", MASCOT_NS).text
            ).group(2)

            # scan_used
            if scan in scan_used:
                index_match, rank_match = scan_used[scan]

                if rank >= rank_match:
                    continue
                else:
                    del out[index_match]

            scan_used[scan] = (index, rank)
            out.append(
                PeptideQuery(
                    accession,
                    prot_desc,
                    query,
                    rank,
                    pep_score,
                    exp_mz,
                    exp_z,
                    pep_seq,
                    var_mods,
                    scan,
                )
            )
            index += 1

    return fixed_mods, var_mods, out


def read_mascot_xml(xml_name):
    """
    Parse a MASCOT XML file.
<commit_msg>Fixed bug where var_mods was being overridden<commit_after>"""
Provides functionality for interacting with MASCOT data.
"""

import os
from collections import namedtuple
import re
import xml.etree.ElementTree as ET

from pyproteome import paths

MASCOT_NS = {
    "mascot":
        "http://www.matrixscience.com/xmlns/schema/mascot_search_results_2",
}

PeptideQuery = namedtuple(
    "PeptideQuery",
    [
        "gi",
        "protein",
        "query",
        "pep_rank",
        "pep_score",
        "pep_exp_mz",
        "pep_exp_z",
        "pep_seq",
        "pep_var_mods",
        "scan",
    ],
)


def _parse_mascot_2_4_1(root):
    fixed_mods = [
        i.text
        for i in root.findall(
            "mascot:fixed_mods/mascot:modification/mascot:name",
            MASCOT_NS,
        )
    ]
    variable_mods = [
        i.text
        for i in root.findall(
            "mascot:variable_mods/mascot:modification/mascot:name",
            MASCOT_NS,
        )
    ]

    scan_used = {}
    index = 0
    out = []

    for hit in root.findall("mascot:hits/mascot:hit", MASCOT_NS):
        accession = hit.find("mascot:protein", MASCOT_NS).get("accession")
        prot_desc = hit.find("mascot:protein/mascot:prot_desc", MASCOT_NS).text

        for peptide in hit.findall("mascot:protein/mascot:peptide", MASCOT_NS):
            query = peptide.get("query")
            rank = peptide.get("rank")
            pep_score = peptide.find("mascot:pep_score", MASCOT_NS).text
            exp_mz = peptide.find("mascot:pep_exp_mz", MASCOT_NS).text
            exp_z = peptide.find("mascot:pep_exp_z", MASCOT_NS).text
            pep_seq = peptide.find("mascot:pep_seq", MASCOT_NS).text

            var_mods = peptide.find("mascot:pep_var_mod", MASCOT_NS).text

            if var_mods:
                var_mods = [
                    re.match(
                        "((\d+) )?(.*)",
                        mod.strip()
                    ).group(2, 3)
                    for mod in var_mods.split(";")
                ]
                var_mods = [
                    (count if count else 1, name)
                    for count, name in var_mods
                ]
            else:
                var_mods = []

            scan = re.search(
                "(scans:|Cmpd_)(\d+)",
                peptide.find("mascot:pep_scan_title", MASCOT_NS).text
            ).group(2)

            # scan_used
            if scan in scan_used:
                index_match, rank_match = scan_used[scan]

                if rank >= rank_match:
                    continue
                else:
                    del out[index_match]

            scan_used[scan] = (index, rank)
            out.append(
                PeptideQuery(
                    accession,
                    prot_desc,
                    query,
                    rank,
                    pep_score,
                    exp_mz,
                    exp_z,
                    pep_seq,
                    var_mods,
                    scan,
                )
            )
            index += 1

    return fixed_mods, variable_mods, out


def read_mascot_xml(xml_name):
    """
    Parse a MASCOT XML file.

{'fraction_non_alphanumeric': 0.1026771653543307, 'fraction_numerical': 0.0031496062992125984, 'mean_word_length': 1.3600891861761426, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '728014', 'n_tokens_mistral': 2176, 'n_tokens_neox': 1992, 'n_words': 350}