<commit_before>###########################################################################
#                                                                         #
#    physical_validation,                                                 #
#    a python package to test the physical validity of MD results         #
#                                                                         #
#    Written by <NAME> <<EMAIL>>           #
#               <NAME> <<EMAIL>>                 #
#                                                                         #
#    Copyright (C) 2012 University of Virginia                            #
#              (C) 2017 University of Colorado Boulder                    #
#                                                                         #
#    This library is free software; you can redistribute it and/or        #
#    modify it under the terms of the GNU Lesser General Public           #
#    License as published by the Free Software Foundation; either         #
#    version 2.1 of the License, or (at your option) any later version.   #
#                                                                         #
#    This library is distributed in the hope that it will be useful,      #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of       #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    #
#    Lesser General Public License for more details.                      #
#                                                                         #
#    You should have received a copy of the GNU Lesser General Public     #
#    License along with this library; if not, write to the                #
#    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,     #
#    Boston, MA 02110-1301 USA                                            #
#                                                                         #
###########################################################################
r"""
This module contains low-level functionality of the
`physical_validation.kinetic_energy` module. The functions in this module
should generally not be called directly. Please use the high-level
functions from `physical_validation.kinetic energy`.
"""
import multiprocessing as mproc
import warnings

import numpy as np
import scipy.stats as stats

from ..util import trajectory
from . import plot


def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)


def temperature(kin, ndof, kb=8.314e-3):
    r"""
    Calculates the temperature acccording to the equipartition theorem.

    .. math::
        T(K) = \frac{2K}{N k_B}

    Parameters
    ----------
    kin : float
        Kinetic energy.
    ndof : float
        Number of degrees of freedom.
    kb : float
        Boltzmann constant :math:`k_B`. Default: 8.314e-3 (kJ/mol).

    Returns
    -------
    temperature : float
        Calculated temperature.
    """
    # ndof * kb * T = 2 * kin
    if isclose(ndof, 0):
        return 0
    return 2 * float(kin) / (float(ndof) * float(kb))


def check_distribution(
    kin,
    temp,
    ndof,
    kb=8.314e-3,
    verbosity=2,
    screen=False,
    filename=None,
    ene_unit=None,
    temp_unit=None,
):
    r"""
    Checks if a kinetic energy trajectory is Maxwell-Boltzmann distributed.

    .. warning: This is a low-level function. Additionally to being less
       user-friendly, there is a higher probability of erroneous and / or
       badly documented behavior due to unexpected inputs. Consider using
       the high-level version based on the SimulationData object. See
       physical_validation.kinetic_energy.check_mb_ensemble for more
       information and full documentation.

    Parameters
    ----------
    kin : array-like
        Kinetic energy snapshots of the system.
    temp : float
        Target temperature of the system. Used to construct the
        Maxwell-Boltzmann distribution.
    ndof : float
        Number of degrees of freedom in the system. Used to construct the
        Maxwell-Boltzmann distribution.
    kb : float
        Boltzmann constant :math:`k_B`. Default: 8.314e-3 (kJ/mol).
    verbosity : int
        0: Silent.
        1: Print minimal information.
        2: Print result details.
        3: Print additional information.
        Default: 2.
    screen : bool
        Plot distributions on screen. Default: False.
    filename : string
        Plot distributions to `filename`.pdf. Default: None.
    ene_unit : string
        Energy unit - used for output only.
    temp_unit : string
        Temperature unit - used for output only.

    Returns
    -------
    result : float
        The p value of the test.

    See Also
    --------
    physical_validation.kinetic_energy.distribution : High-level version
    """

    # Discard burn-in period and time-correlated frames
    kin = trajectory.prepare(kin, verbosity=verbosity, name="Kinetic energy")
    kt = kb * temp

    if ndof <= 0:
        warnings.warn("Zero degrees of freedom!")
        p = np.float("NaN")
    else:
        d, p = stats.kstest(kin, "gamma", (ndof / 2, 0, kt))

    # ====================== #
    # Plot to screen or file #
    # ====================== #
    do_plot = screen or filename is not None
    if do_plot:
        ana_dist = stats.gamma(ndof / 2, scale=kt)
        ana_kin = np.linspace(ana_dist.ppf(0.0001), ana_dist.ppf(0.9999), 200)
        ana_hist = ana_dist.pdf(ana_kin)

        tunit = ""
        if temp_unit is not None:
            tunit = temp_unit

        data = [
            {
                "y": kin,
                "hist": int(len(kin) / 150),
                "args": dict(label="Trajectory", density=True, alpha=0.5),
            }<commit_msg>Fix short trajectory plotting (#77)<commit_after>###########################################################################
#                                                                         #
#    physical_validation,                                                 #
#    a python package to test the physical validity of MD results         #
#                                                                         #
#    Written by <NAME> <<EMAIL>>           #
#               <NAME> <<EMAIL>>                 #
#                                                                         #
#    Copyright (C) 2012 University of Virginia                            #
#              (C) 2017 University of Colorado Boulder                    #
#                                                                         #
#    This library is free software; you can redistribute it and/or        #
#    modify it under the terms of the GNU Lesser General Public           #
#    License as published by the Free Software Foundation; either         #
#    version 2.1 of the License, or (at your option) any later version.   #
#                                                                         #
#    This library is distributed in the hope that it will be useful,      #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of       #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    #
#    Lesser General Public License for more details.                      #
#                                                                         #
#    You should have received a copy of the GNU Lesser General Public     #
#    License along with this library; if not, write to the                #
#    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,     #
#    Boston, MA 02110-1301 USA                                            #
#                                                                         #
###########################################################################
r"""
This module contains low-level functionality of the
`physical_validation.kinetic_energy` module. The functions in this module
should generally not be called directly. Please use the high-level
functions from `physical_validation.kinetic energy`.
"""
import multiprocessing as mproc
import warnings

import numpy as np
import scipy.stats as stats

from ..util import trajectory
from . import plot


def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)


def temperature(kin, ndof, kb=8.314e-3):
    r"""
    Calculates the temperature acccording to the equipartition theorem.

    .. math::
        T(K) = \frac{2K}{N k_B}

    Parameters
    ----------
    kin : float
        Kinetic energy.
    ndof : float
        Number of degrees of freedom.
    kb : float
        Boltzmann constant :math:`k_B`. Default: 8.314e-3 (kJ/mol).

    Returns
    -------
    temperature : float
        Calculated temperature.
    """
    # ndof * kb * T = 2 * kin
    if isclose(ndof, 0):
        return 0
    return 2 * float(kin) / (float(ndof) * float(kb))


def check_distribution(
    kin,
    temp,
    ndof,
    kb=8.314e-3,
    verbosity=2,
    screen=False,
    filename=None,
    ene_unit=None,
    temp_unit=None,
):
    r"""
    Checks if a kinetic energy trajectory is Maxwell-Boltzmann distributed.

    .. warning: This is a low-level function. Additionally to being less
       user-friendly, there is a higher probability of erroneous and / or
       badly documented behavior due to unexpected inputs. Consider using
       the high-level version based on the SimulationData object. See
       physical_validation.kinetic_energy.check_mb_ensemble for more
       information and full documentation.

    Parameters
    ----------
    kin : array-like
        Kinetic energy snapshots of the system.
    temp : float
        Target temperature of the system. Used to construct the
        Maxwell-Boltzmann distribution.
    ndof : float
        Number of degrees of freedom in the system. Used to construct the
        Maxwell-Boltzmann distribution.
    kb : float
        Boltzmann constant :math:`k_B`. Default: 8.314e-3 (kJ/mol).
    verbosity : int
        0: Silent.
        1: Print minimal information.
        2: Print result details.
        3: Print additional information.
        Default: 2.
    screen : bool
        Plot distributions on screen. Default: False.
    filename : string
        Plot distributions to `filename`.pdf. Default: None.
    ene_unit : string
        Energy unit - used for output only.
    temp_unit : string
        Temperature unit - used for output only.

    Returns
    -------
    result : float
        The p value of the test.

    See Also
    --------
    physical_validation.kinetic_energy.distribution : High-level version
    """

    # Discard burn-in period and time-correlated frames
    kin = trajectory.prepare(kin, verbosity=verbosity, name="Kinetic energy")
    kt = kb * temp

    if ndof <= 0:
        warnings.warn("Zero degrees of freedom!")
        p = np.float("NaN")
    else:
        d, p = stats.kstest(kin, "gamma", (ndof / 2, 0, kt))

    # ====================== #
    # Plot to screen or file #
    # ====================== #
    do_plot = screen or filename is not None
    if do_plot:
        ana_dist = stats.gamma(ndof / 2, scale=kt)
        ana_kin = np.linspace(ana_dist.ppf(0.0001), ana_dist.ppf(0.9999), 200)
        ana_hist = ana_dist.pdf(ana_kin)

        tunit = ""
        if temp_unit is not None:
            tunit = temp_unit

        # The following settings usually result in smooth histograms,
        # but can be reconsidered
        min_num_hist_bins = 5
        min_num_data_per_bin = 150
        if (int(len(kin) / min_num_data_per_bin)) < min_num_hist_bins:
            warnings.warn(
                "\nFor smooth histograms, we recommend at least {} bins and {} data points per bin.\n"
                "Your current trajectory has only {} data points.\n"
                "Setting number of bins to {}. Consider a longer trajectory for smoother "
                "histograms!".format(
                    min_num_hist_bins, min_num_data_per_bin, len(kin), min_num_hist_bins
                )
            )
        num_hist_bins = max(min_num_hist_bins, int(len(kin) / min_num_data_per_bin))

        data = [
            {
                "y": kin,
                "hist": max(min_num_hist_bins, num_hist_bins),
                "args": dict(label="Trajectory", density=True, alpha=0.5),
            }
{'fraction_non_alphanumeric': 0.11009100426834179, 'fraction_numerical': 0.012966094869936377, 'mean_word_length': 1.6342808655070005, 'pattern_counts': {'":': 6, '<': 20, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 50, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '662552', 'n_tokens_mistral': 3326, 'n_tokens_neox': 3052, 'n_words': 1097}