<commit_before>#
# scoring_browser --- Simple Qt application for browsing
# scoring outputs in Geant4
#
# Copyright (C) 2012-2014 <NAME>
# (<EMAIL>)
#
# This file may be distributed without limitation.
#
import re
import numpy


class DataMatrix(object):
    """A 3D matrix with data.

    Based on numpy ndarray + a few more methods.
    It can be built from the scoring files made command-based
    Geant4 scoring (either a string of from_file method).

    The indexing is (mostly) forwarded to the inner numpy array.

    * DataMatrix.relative provides a copy of the matrix scaled
    relative to the maximum value (it is stored in the matrix
    after first requested).

    * DataMatrix.reduced() returns a copy of the matrix with values summed
    over volumes of defined size (if division is possible).
    """
    def __init__(self, source=None, header=None):
        self.header = ""
        if source is None:
            self.data_array = None
        elif isinstance(source, numpy.ndarray):
            self.data_array = source
        else:
            points = []
            linePattern = re.compile("(\d+),(\d+),(\d+),([0-9.e\-]*)")
            commentLinePattern = re.compile("#.*")

            for line in source.splitlines():
                match = linePattern.match(line)
                if match:
                    x = int(match.group(1))
                    y = int(match.group(2))
                    z = int(match.group(3))
                    val = float(match.group(4))
                    points.append([x, y, z, val])

                match = commentLinePattern.match(line)
                if match:
                    self.header += line + "\n"

            sizeX = max(l[0] for l in points) + 1
            sizeY = max(l[1] for l in points) + 1
            sizeZ = max(l[2] for l in points) + 1

            self.data_array = numpy.ndarray(shape=(sizeX, sizeY, sizeZ),
                                            dtype=float)
            if len(points) != self.size:
                raise Exception("Incomplete file")

            for p in points:
                self.data_array[p[0], p[1], p[2]] = p[3]
        if header:
            self.header = header

    def copy(self):
        """Return a copy of the matrix.

        The result will not share memory with the original matrix.
        """
        return DataMatrix(self.data_array.copy())

    @staticmethod
    def from_file(file_name):
        """Read the matrix from scoring file."""
        with open(file_name) as f:
            text = f.read()
            return DataMatrix(text)

    def to_file(self, file):
        """Write the matrix to a scoring file."""
        file.write(self.header)
        # TODO: Probably not finished

    def empty(self):
        return not(self.data_array)

    def __add__(self, other):
        return DataMatrix(self.data_array + other.data_array)

    def __sub__(self, other):
        return DataMatrix(self.data_array - other.data_array)

    def __getitem__(self, index):
        """ Array indexing.

        If the index is 4-elements long and the last one is "True",
        relative value is taken.
        """
        if not hasattr(index, "__len__"):
            return self.data_array[index]
        if len(index) == 4 and index[3]:
            m = self.relative
        else:
            m = self
        return m.data_array.__getitem__(index[0:3])

    def __setitem__(self, index, value):
        self.data_array.__setitem__(index, value)

    def value_at(self, x, y, z):
        return self.data_array[x, y, z]

    def relative_value_at(self, x, y, z):
        return self.relative.value_at(x, y, z)

    @property
    def size(self):
        return self.data_array.size

    @property
    def shape(self):
        return self.data_array.shape

    @property<commit_msg>DataMatrix.__str__<commit_after>#
# scoring_browser --- Simple Qt application for browsing
# scoring outputs in Geant4
#
# Copyright (C) 2012-2014 <NAME>
# (<EMAIL>)
#
# This file may be distributed without limitation.
#
import re
import numpy


class DataMatrix(object):
    """A 3D matrix with data.

    Based on numpy ndarray + a few more methods.
    It can be built from the scoring files made command-based
    Geant4 scoring (either a string of from_file method).

    The indexing is (mostly) forwarded to the inner numpy array.

    * DataMatrix.relative provides a copy of the matrix scaled
    relative to the maximum value (it is stored in the matrix
    after first requested).

    * DataMatrix.reduced() returns a copy of the matrix with values summed
    over volumes of defined size (if division is possible).
    """
    def __init__(self, source=None, header=None):
        self.header = ""
        if source is None:
            self.data_array = None
        elif isinstance(source, numpy.ndarray):
            self.data_array = source
        else:
            points = []
            linePattern = re.compile("(\d+),(\d+),(\d+),([0-9.e\-]*)")
            commentLinePattern = re.compile("#.*")

            for line in source.splitlines():
                match = linePattern.match(line)
                if match:
                    x = int(match.group(1))
                    y = int(match.group(2))
                    z = int(match.group(3))
                    val = float(match.group(4))
                    points.append([x, y, z, val])

                match = commentLinePattern.match(line)
                if match:
                    self.header += line + "\n"

            sizeX = max(l[0] for l in points) + 1
            sizeY = max(l[1] for l in points) + 1
            sizeZ = max(l[2] for l in points) + 1

            self.data_array = numpy.ndarray(shape=(sizeX, sizeY, sizeZ),
                                            dtype=float)
            if len(points) != self.size:
                raise Exception("Incomplete file")

            for p in points:
                self.data_array[p[0], p[1], p[2]] = p[3]
        if header:
            self.header = header

    def copy(self):
        """Return a copy of the matrix.

        The result will not share memory with the original matrix.
        """
        return DataMatrix(self.data_array.copy())

    @staticmethod
    def from_file(file_name):
        """Read the matrix from scoring file."""
        with open(file_name) as f:
            text = f.read()
            return DataMatrix(text)

    def to_file(self, file):
        """Write the matrix to a scoring file."""
        file.write(self.header)
        # TODO: Probably not finished

    def empty(self):
        return not(self.data_array)

    def __add__(self, other):
        return DataMatrix(self.data_array + other.data_array)

    def __sub__(self, other):
        return DataMatrix(self.data_array - other.data_array)

    def __getitem__(self, index):
        """ Array indexing.

        If the index is 4-elements long and the last one is "True",
        relative value is taken.
        """
        if not hasattr(index, "__len__"):
            return self.data_array[index]
        if len(index) == 4 and index[3]:
            m = self.relative
        else:
            m = self
        return m.data_array.__getitem__(index[0:3])

    def __setitem__(self, index, value):
        self.data_array.__setitem__(index, value)

    def __str__(self):
        return "DataMatrix(%d, %d, %d)" % (self.shape)

    def value_at(self, x, y, z):
        return self.data_array[x, y, z]

    def relative_value_at(self, x, y, z):
        return self.relative.value_at(x, y, z)

    @property
    def size(self):
        return self.data_array.size

    @property
    def shape(self):
        return self.data_array.shape

    @property
{'fraction_non_alphanumeric': 0.10525634386328327, 'fraction_numerical': 0.008285862247540134, 'mean_word_length': 1.8954272863568216, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3078546', 'n_tokens_mistral': 2269, 'n_tokens_neox': 2151, 'n_words': 698}