<commit_before># -*- coding: utf-8 -*-

from collections import defaultdict, Counter
from itertools import chain, ifilter, izip
import re

import numpy as np

from pyfr.readers import BaseReader
from pyfr.readers.nodemaps import GmshNodeMaps


def msh_section(mshit, section):
    endln = '$End{}\n'.format(section)
    endix = int(next(mshit)) - 1

    for i, l in enumerate(mshit):
        if l == endln:
            raise ValueError('Unexpected end of section $' + section)

        yield l

        if i == endix:
            break
    else:
        raise ValueError('Unexpected EOF')

    if next(mshit) != endln:
        raise ValueError('Expected $End' + section)


class GmshReader(BaseReader):
    # Supported file types and extensions
    name = 'gmsh'
    extn = ['.msh']

    # Gmsh element types to PyFR type (petype) + sizes
    _etype_map = {1: ('line', 2),  8: ('line', 3), 26: ('line', 4),
                  2: ('tri', 3),   9: ('tri', 6),  21: ('tri', 10),
                  3: ('quad', 4), 10: ('quad', 9), 36: ('quad', 16),
                  4: ('tet', 4),  11: ('tet', 10), 29: ('tet', 20),
                  5: ('hex', 8),  12: ('hex', 27), 92: ('hex', 64),
                  6: ('pri', 6),  13: ('pri', 18),
                  7: ('pyr', 5),  14: ('pyr', 14)}

    # Number of nodes in the first-order representation an element
    _petype_focount = {v[0]: v[1] for k, v in _etype_map.items() if k < 8}

    # Dimensionality of each element type
    _petype_ndim = {'tri': 2, 'quad': 2,
                    'tet': 3, 'hex': 3, 'pri': 3, 'pyr': 3}

    # Number of faces of each type per element
    _petype_ftcount = {'tri': {'line': 3},
                       'quad': {'line': 4},
                       'tet': {'tri': 4},
                       'hex': {'quad': 6},
                       'pri': {'quad': 3, 'tri': 2},
                       'pyr': {'quad': 1, 'tri': 4}}

    def __init__(self, msh):
        if isinstance(msh, basestring):
            msh = open(msh)

        # Get an iterator over the lines of the mesh
        mshit = iter(msh)

        # Required section readers
        sect_map = {'MeshFormat': self._read_mesh_format,
                    'Nodes': self._read_nodes,
                    'Elements': self._read_eles,
                    'PhysicalNames': self._read_phys_names}
        req_sect = frozenset(sect_map)

        # Seen sections
        seen_sect = set()

        for l in ifilter(lambda l: l != '\n', mshit):
            # Ensure we have encountered a section
            if not l.startswith('$'):
                raise ValueError('Expected a mesh section')

            # Strip the '$' and '\n' to get the section name
            sect = l[1:-1]

            # If the section is known then read it
            if sect in sect_map:
                sect_map[sect](mshit)
                seen_sect.add(sect)
            # Else skip over it
            else:
                endsect = '$End{}\n'.format(sect)

                for el in mshit:
                    if el == endsect:
                        break
                else:
                    raise ValueError('Expected $End' + sect)

        # Check that all of the required sections are present
        if seen_sect != req_sect:
            missing = req_sect - seen_sect
            raise ValueError('Required sections: {} not found'
                             .format(missing))

    def _read_mesh_format(self, mshit):
        ver, ftype, dsize = next(mshit).split()

        if ver != '2.2':
            raise ValueError('Invalid mesh version')
        if ftype != '0':
            raise ValueError('Invalid file type')
        if dsize != '8':
            raise ValueError('Invalid data size')

        if next(mshit) != '$EndMeshFormat\n':
            raise ValueError('Expected $EndMeshFormat')

    def _read_phys_names(self, msh):
        # Physical entities can be divided up into:
        #  - fluid elements ('the mesh')
        #  - boundary faces
        #  - periodic faces
        self._felespent = None
        self._bfacespents = {}
        self._pfacespents = defaultdict(list)

        # Extract the physical names
        for l in msh_section(msh, 'PhysicalNames'):
            m = re.match(r'(\d+) (\d+) "((?:[^"\\]|\\.)*)"$', l)
            if not m:
                raise ValueError('Malformed physical entity')

            pent, name = int(m.group(2)), m.group(3).lower()

            # Fluid elements
            if name == 'fluid':
                self._felespent = pent
            # Periodic boundary faces
            elif name.startswith('periodic'):
                p = re.match(r'periodic[ -_]([a-z0-9]+)[ -_](l|r)$', name)
                if not p:
                    raise ValueError('Invalid periodic boundary condition')

                self._pfacespents[p.group(1)].append(pent)
            # Other boundary faces
            else:
                self._bfacespents[name] = pent

        if self._felespent is None:
            raise ValueError('No fluid elements in mesh')

        if any(len(pf) != 2 for pf in self._pfacespents.itervalues()):
            raise ValueError('Unpaired periodic boundary in mesh')

    def _read_nodes(self, msh):
        self._nodepts = nodepts = {}

        for l in msh_section(msh, 'Nodes'):
            nv = l.split()
            nodepts[int(nv[0])] = [float(x) for x in nv[1:]]

    def _read_eles(self, msh):
        elenodes = defaultdict(list)
        eleparts = defaultdict(list)

        for l in msh_section(msh, 'Elements'):
            # Extract the raw element data
            elei = [int(i) for i in l.split()]
            enum, etype, entags = elei[:3]<commit_msg>Squeeze five percent or so out of the Gmsh reader.<commit_after># -*- coding: utf-8 -*-

from collections import defaultdict, Counter
from itertools import chain, ifilter, izip
import re

import numpy as np

from pyfr.readers import BaseReader
from pyfr.readers.nodemaps import GmshNodeMaps


def msh_section(mshit, section):
    endln = '$End{}\n'.format(section)
    endix = int(next(mshit)) - 1

    for i, l in enumerate(mshit):
        if l == endln:
            raise ValueError('Unexpected end of section $' + section)

        yield l

        if i == endix:
            break
    else:
        raise ValueError('Unexpected EOF')

    if next(mshit) != endln:
        raise ValueError('Expected $End' + section)


class GmshReader(BaseReader):
    # Supported file types and extensions
    name = 'gmsh'
    extn = ['.msh']

    # Gmsh element types to PyFR type (petype) + sizes
    _etype_map = {1: ('line', 2),  8: ('line', 3), 26: ('line', 4),
                  2: ('tri', 3),   9: ('tri', 6),  21: ('tri', 10),
                  3: ('quad', 4), 10: ('quad', 9), 36: ('quad', 16),
                  4: ('tet', 4),  11: ('tet', 10), 29: ('tet', 20),
                  5: ('hex', 8),  12: ('hex', 27), 92: ('hex', 64),
                  6: ('pri', 6),  13: ('pri', 18),
                  7: ('pyr', 5),  14: ('pyr', 14)}

    # Number of nodes in the first-order representation an element
    _petype_focount = {v[0]: v[1] for k, v in _etype_map.items() if k < 8}

    # Dimensionality of each element type
    _petype_ndim = {'tri': 2, 'quad': 2,
                    'tet': 3, 'hex': 3, 'pri': 3, 'pyr': 3}

    # Number of faces of each type per element
    _petype_ftcount = {'tri': {'line': 3},
                       'quad': {'line': 4},
                       'tet': {'tri': 4},
                       'hex': {'quad': 6},
                       'pri': {'quad': 3, 'tri': 2},
                       'pyr': {'quad': 1, 'tri': 4}}

    def __init__(self, msh):
        if isinstance(msh, basestring):
            msh = open(msh)

        # Get an iterator over the lines of the mesh
        mshit = iter(msh)

        # Required section readers
        sect_map = {'MeshFormat': self._read_mesh_format,
                    'Nodes': self._read_nodes,
                    'Elements': self._read_eles,
                    'PhysicalNames': self._read_phys_names}
        req_sect = frozenset(sect_map)

        # Seen sections
        seen_sect = set()

        for l in ifilter(lambda l: l != '\n', mshit):
            # Ensure we have encountered a section
            if not l.startswith('$'):
                raise ValueError('Expected a mesh section')

            # Strip the '$' and '\n' to get the section name
            sect = l[1:-1]

            # If the section is known then read it
            if sect in sect_map:
                sect_map[sect](mshit)
                seen_sect.add(sect)
            # Else skip over it
            else:
                endsect = '$End{}\n'.format(sect)

                for el in mshit:
                    if el == endsect:
                        break
                else:
                    raise ValueError('Expected $End' + sect)

        # Check that all of the required sections are present
        if seen_sect != req_sect:
            missing = req_sect - seen_sect
            raise ValueError('Required sections: {} not found'
                             .format(missing))

    def _read_mesh_format(self, mshit):
        ver, ftype, dsize = next(mshit).split()

        if ver != '2.2':
            raise ValueError('Invalid mesh version')
        if ftype != '0':
            raise ValueError('Invalid file type')
        if dsize != '8':
            raise ValueError('Invalid data size')

        if next(mshit) != '$EndMeshFormat\n':
            raise ValueError('Expected $EndMeshFormat')

    def _read_phys_names(self, msh):
        # Physical entities can be divided up into:
        #  - fluid elements ('the mesh')
        #  - boundary faces
        #  - periodic faces
        self._felespent = None
        self._bfacespents = {}
        self._pfacespents = defaultdict(list)

        # Extract the physical names
        for l in msh_section(msh, 'PhysicalNames'):
            m = re.match(r'(\d+) (\d+) "((?:[^"\\]|\\.)*)"$', l)
            if not m:
                raise ValueError('Malformed physical entity')

            pent, name = int(m.group(2)), m.group(3).lower()

            # Fluid elements
            if name == 'fluid':
                self._felespent = pent
            # Periodic boundary faces
            elif name.startswith('periodic'):
                p = re.match(r'periodic[ -_]([a-z0-9]+)[ -_](l|r)$', name)
                if not p:
                    raise ValueError('Invalid periodic boundary condition')

                self._pfacespents[p.group(1)].append(pent)
            # Other boundary faces
            else:
                self._bfacespents[name] = pent

        if self._felespent is None:
            raise ValueError('No fluid elements in mesh')

        if any(len(pf) != 2 for pf in self._pfacespents.itervalues()):
            raise ValueError('Unpaired periodic boundary in mesh')

    def _read_nodes(self, msh):
        self._nodepts = nodepts = {}

        for l in msh_section(msh, 'Nodes'):
            nv = l.split()
            nodepts[int(nv[0])] = np.array([float(x) for x in nv[1:]])

    def _read_eles(self, msh):
        elenodes = defaultdict(list)
        eleparts = defaultdict(list)

        for l in msh_section(msh, 'Elements'):
            # Extract the raw element data
            elei = [int(i) for i in l.split()]
            enum, etype, entags = elei[:3]
{'fraction_non_alphanumeric': 0.13040807371654234, 'fraction_numerical': 0.015796401930671347, 'mean_word_length': 1.7056030389363723, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '4079203', 'n_tokens_mistral': 3598, 'n_tokens_neox': 3319, 'n_words': 1046}