<commit_before>"""
   Copyright 2013 <NAME> (aka Daniel)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

"""
RESOURCES:
http://wesmckinney.com/blog/?p=278
http://docs.cython.org/src/userguide/numpy_tutorial.html
"""

from __future__ import print_function, division
import numpy as np
cimport numpy as np
import pandas as pd

# Data types for timestamps (TS = TimeStamp)
TS_DTYPE = np.uint64
ctypedef np.uint64_t TS_DTYPE_t

# Data types for power data (PW = PoWer)
PW_DTYPE = np.float32
ctypedef np.float32_t PW_DTYPE_t

def _sanity_check_input_to_steady_state_detectors(
                  np.ndarray[PW_DTYPE_t, ndim=1] watts,
                  Py_ssize_t min_n_samples, 
                  PW_DTYPE_t max_range):
    if watts is None or min_n_samples is None or max_range is None:
        raise ValueError('Do not use None for any arguments.')
    if watts.size < min_n_samples:
        raise ValueError('watts array must have more than '
                         'min_n_samples={} elements!'.format(min_n_samples))
    if np.any(np.isnan(watts)):
        raise ValueError('Please remove all NaNs!')


def steady_states(series,
                  Py_ssize_t min_n_samples=3, 
                  PW_DTYPE_t max_range=15):
    """Steady_state detector based on the definition of steady states given
    in Hart 1992 [1]_

    Parameters
    ----------
    series : pd.Series
        Watts. Must be np.float_32

    min_n_samples : int, optional
        Defaults to 3. Minimum number of consecutive samples per steady state.
        Hart used 3.

    max_range : float, optional
        Defaults to 15 Watts. Maximum permissible range between the lowest
        and highest value per steady state. Hart used 15.
    

    Returns
    -------
    steady_states : pd.DataFrame
        Each row is a steady state.  Columns:
           * index: datetime of start of steady state
           * end: datetime of end of steady state
           * power: mean power for steady state

    References
    ----------
    .. [1] <NAME>. (1992). "Nonintrusive appliance load monitoring."
       Proceedings of the IEEE, 80(12), 1870–1891. doi:10.1109/5.192069
       page 1882, under the heading 'C. Edge Detection'
<commit_msg>Added some more documentation to steady_states()<commit_after>"""
   Copyright 2013 <NAME> (aka Daniel)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

"""
RESOURCES:
http://wesmckinney.com/blog/?p=278
http://docs.cython.org/src/userguide/numpy_tutorial.html
"""

from __future__ import print_function, division
import numpy as np
cimport numpy as np
import pandas as pd

# Data types for timestamps (TS = TimeStamp)
TS_DTYPE = np.uint64
ctypedef np.uint64_t TS_DTYPE_t

# Data types for power data (PW = PoWer)
PW_DTYPE = np.float32
ctypedef np.float32_t PW_DTYPE_t

def _sanity_check_input_to_steady_state_detectors(
                  np.ndarray[PW_DTYPE_t, ndim=1] watts,
                  Py_ssize_t min_n_samples, 
                  PW_DTYPE_t max_range):
    if watts is None or min_n_samples is None or max_range is None:
        raise ValueError('Do not use None for any arguments.')
    if watts.size < min_n_samples:
        raise ValueError('watts array must have more than '
                         'min_n_samples={} elements!'.format(min_n_samples))
    if np.any(np.isnan(watts)):
        raise ValueError('Please remove all NaNs!')


def steady_states(series,
                  Py_ssize_t min_n_samples=3, 
                  PW_DTYPE_t max_range=15):
    """Steady_state detector based on the definition of steady states given
    in Hart 1992 [1]_

    It simply finds segments of 3 or more consecutive samples all of
    which fall within a 15 Watt window. It works OK for very simple
    appliances like toasters. But even something fairly simple but
    with quite a lot of variance like a TV confuses it a lot. But this
    steady_states() detector is very fast (both because the algo is
    simple and because it's implemented in Cython ;)

    Parameters
    ----------
    series : pd.Series
        Watts. Must be np.float_32

    min_n_samples : int, optional
        Defaults to 3. Minimum number of consecutive samples per steady state.
        Hart used 3.

    max_range : float, optional
        Defaults to 15 Watts. Maximum permissible range between the lowest
        and highest value per steady state. Hart used 15.
    

    Returns
    -------
    steady_states : pd.DataFrame
        Each row is a steady state.  Columns:
           * index: datetime of start of steady state
           * end: datetime of end of steady state
           * power: mean power for steady state

    References
    ----------
    .. [1] <NAME>. (1992). "Nonintrusive appliance load monitoring."
       Proceedings of the IEEE, 80(12), 1870–1891. doi:10.1109/5.192069
       page 1882, under the heading 'C. Edge Detection'

{'fraction_non_alphanumeric': 0.0734492160872529, 'fraction_numerical': 0.024369461486025902, 'mean_word_length': 2.6476072094468615, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1051728', 'n_tokens_mistral': 1837, 'n_tokens_neox': 1664, 'n_words': 659}