<commit_before># Copyright 2016 Raytheon BBN Technologies
#
# 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

__all__ = ['Channelizer']

import os
import platform
from copy import deepcopy

import numpy as np
import scipy.signal

from .filter import Filter
from auspex.parameter import Parameter, IntParameter, FloatParameter
from auspex.stream import  DataStreamDescriptor, InputConnector, OutputConnector
from auspex.log import logger

try:
    # load libchannelizer to access Intel IPP filtering functions
    import numpy.ctypeslib as npct
    from ctypes import c_int, c_size_t
    np_float  = npct.ndpointer(dtype=np.float32, flags='C_CONTIGUOUS')

    libchannelizer_path = os.path.abspath(os.path.join( os.path.dirname(__file__), "libchannelizer"))
    if "Windows" in platform.platform():
        os.environ["PATH"] += ";" + libchannelizer_path
    libipp = npct.load_library("libchannelizer",  libchannelizer_path)
    libipp.filter_records_fir.argtypes = [np_float, c_size_t, c_int, np_float, c_size_t, c_size_t, np_float]
    libipp.filter_records_iir.argtypes = [np_float, c_size_t, np_float, c_size_t, c_size_t, np_float]
    libipp.init()

    load_fallback = False
except:
    logger.warning("Could not load channelizer library; falling back to python methods.")
    load_fallback = True

class Channelizer(Filter):
    """Digital demodulation and filtering to select a particular frequency multiplexed channel. If
    an axis name is supplied to `follow_axis` then the filter will demodulate at the freqency
    `axis_frequency_value - follow_freq_offset` otherwise it will demodulate at `frequency`. Note that
    the filter coefficients are still calculated with respect to the `frequency` paramter, so it should
    be chosen accordingly when `follow_axis` is defined."""

    sink               = InputConnector()
    source             = OutputConnector()
    follow_axis        = Parameter(default="") # Name of the axis to follow
    follow_freq_offset = FloatParameter(default=0.0) # Offset
    decimation_factor  = IntParameter(value_range=(1,100), default=4, snap=1)
    frequency          = FloatParameter(value_range=(-10e9,10e9), increment=1.0e6, default=10e6)
    bandwidth          = FloatParameter(value_range=(0.00, 100e6), increment=0.1e6, default=5e6)

    def __init__(self, frequency=None, bandwidth=None, decimation_factor=None,
                    follow_axis=None, follow_freq_offset=None, **kwargs):
        super(Channelizer, self).__init__(**kwargs)
        if frequency:
            self.frequency.value = frequency
        if bandwidth:
            self.bandwidth.value = bandwidth
        if decimation_factor:
            self.decimation_factor.value = decimation_factor
        if follow_axis:
            self.follow_axis.value = follow_axis
        if follow_freq_offset:
            self.follow_freq_offset.value = follow_freq_offset
        self.quince_parameters = [self.decimation_factor, self.frequency, self.bandwidth]
        self._phase = 0.0

    def final_init(self):
        self.init_filters(self.frequency.value, self.bandwidth.value)

        if self.follow_axis.value is not "":
            self.demod_freqs  = (self.sink.descriptor.expected_tuples(with_metadata=True, as_structured_array=True)[self.follow_axis.value] - self.follow_freq_offset.value)
            self.current_freq = 0
            self.update_references(self.current_freq)
        self.idx = 0

    def update_references(self, frequency):
        # store decimated reference for mix down
        # phase_drift = 2j*np.pi*0.5e-6 * (abs(frequency) - 100e6)
        ref = np.exp(2j*np.pi * -frequency * self.time_pts[::self.d1] + 1j*self._phase, dtype=np.complex64)

        self.reference   = ref
        self.reference_r = np.real(ref)
        self.reference_i = np.imag(ref)

    def init_filters(self, frequency, bandwidth):
        # convert bandwidth normalized to Nyquist interval
        n_bandwidth = bandwidth * self.time_step * 2
        n_frequency = frequency * self.time_step * 2

        # arbitrarily decide on three stage filter pipeline
        # 1. first stage decimating filter on real data
        # 2. second stage decimating filter on mixed product to boost n_bandwidth
        # 3. final channel selecting filter at n_bandwidth/2

        # anecdotally don't decimate more than a factor of eight for stability

        self.decim_factors = [1]*3
        self.filters = [None]*3

        # first stage decimating filter
        # maximize first stage decimation:
        #     * minimize subsequent stages time taken
        #     * filter and decimate while signal is still real
        #     * first stage decimation cannot be too large or then 2omega signal from mixing will alias
        self.d1 = 1
        while (self.d1 < 8) and (2*n_frequency <= 0.8/self.d1) and (self.d1 < self.decimation_factor.value):
            self.d1 *= 2
            n_bandwidth *= 2
            n_frequency *= 2

        if self.d1 > 1:
            # create an anti-aliasing filter
            # pass-band to 0.8 * decimation factor; anecdotally single precision needs order <= 4 for stability
            b,a = scipy.signal.cheby1(4, 3, 0.8/self.d1)
            b = np.float32(b)
            a = np.float32(a)
            self.decim_factors[0] = self.d1
            self.filters[0]  = (b,a)

        # store decimated reference for mix down
        self.update_references(frequency)

        # second stage filter to bring n_bandwidth/2 up
        # decimation cannot be too large or will impinge on channel bandwidth (keep n_bandwidth/2 <= 0.8)
        self.d2 = 1
        while (self.d2 < 8) and ((self.d1*self.d2) < self.decimation_factor.value) and (n_bandwidth/2 <= 0.8):
            self.d2 *= 2
            n_bandwidth *= 2
            n_frequency *= 2

        if self.d2 > 1:
            # create an anti-aliasing filter
            # pass-band to 0.8 * decimation factor; anecdotally single precision needs order <= 4 for stability
            b,a = scipy.signal.cheby1(4, 3, 0.8/self.d2)
            b = np.float32(b)
            a = np.float32(a)
            self.decim_factors[1] = self.d2
            self.filters[1]  = (b,a)

        # final channel selection filter
        if n_bandwidth < 0.1:
            raise ValueError("Insufficient decimation to achieve stable filter: {}.".format(n_bandwidth))

        b,a = scipy.signal.cheby1(4, 3, n_bandwidth/2)
        b = np.float32(b)
        a = np.float32(a)
        self.decim_factors[2] = self.decimation_factor.value // (self.d1*self.d2)
        self.filters[2]  = (b,a)

    def update_descriptors(self):
        logger.debug('Updating Channelizer "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor)

        # extract record time sampling
        self.time_pts = self.sink.descriptor.axes[-1].points
        self.record_length = len(self.time_pts)
        self.time_step = self.time_pts[1] - self.time_pts[0]
        logger.debug("Channelizer time_step = {}".format(self.time_step))

        # update output descriptors
        decimated_descriptor = DataStreamDescriptor()
        decimated_descriptor.axes = self.sink.descriptor.axes[:]
        decimated_descriptor.axes[-1] = deepcopy(self.sink.descriptor.axes[-1])
        decimated_descriptor.axes[-1].points = self.sink.descriptor.axes[-1].points[self.decimation_factor.value-1::self.decimation_factor.value]
        decimated_descriptor.axes[-1].original_points = decimated_descriptor.axes[-1].points
        decimated_descriptor._exp_src = self.sink.descriptor._exp_src
        decimated_descriptor.dtype = np.complex64
        for os in self.source.output_streams:
            os.set_descriptor(decimated_descriptor)
            if os.end_connector is not None:
                os.end_connector.update_descriptors()

    async def process_data(self, data):
        # Assume for now we get a integer number of records at a time
        # TODO: handle partial records
        num_records = data.size // self.record_length
        reshaped_data = np.reshape(data, (num_records, self.record_length), order="C")

        # Update frequency if necessary
        if self.follow_axis.value is not "":
            freq = self.demod_freqs[self.idx+1]
            if freq != self.current_freq:
                self.update_references(freq)
                self.current_freq = freq
            #     # print(f"Channelizer freq now {freq}")
            #     plot_me = True
            # else:
            #     plot_me = False

        self.idx += data.size

        # first stage decimating filter
        if self.filters[0] is None:
            filtered = reshaped_data
        else:
            stacked_coeffs = np.concatenate(self.filters[0])
            # filter
            if np.iscomplexobj(reshaped_data):
                # TODO: compile complex versions of the IPP functions
                filtered_r = np.empty_like(reshaped_data, dtype=np.float32)
                filtered_i = np.empty_like(reshaped_data, dtype=np.float32)
                libipp.filter_records_iir(stacked_coeffs, self.filters[0][0].size-1, np.ascontiguousarray(reshaped_data.real.astype(np.float32)), self.record_length, num_records, filtered_r)
                libipp.filter_records_iir(stacked_coeffs, self.filters[0][0].size-1, np.ascontiguousarray(reshaped_data.imag.astype(np.float32)), self.record_length, num_records, filtered_i)
                filtered = filtered_r + 1j*filtered_i
                # decimate
                if self.decim_factors[0] > 1:
                    filtered = filtered[:, ::self.decim_factors[0]]
            else:
                filtered = np.empty_like(reshaped_data)
                libipp.filter_records_iir(stacked_coeffs, self.filters[0][0].size-1, reshaped_data, self.record_length, num_records, filtered)

                # decimate
                if self.decim_factors[0] > 1:
                    filtered = filtered[:, ::self.decim_factors[0]]

        # mix with reference
        # keep real and imaginary separate for filtering below
        if np.iscomplexobj(reshaped_data):
            filtered *= self.reference
            filtered_r = filtered.real
            filtered_i = filtered.imag
        else:
            filtered_r = self.reference_r * filtered
            filtered_i = self.reference_i * filtered

        # import pdb; pdb.set_trace()
        # if plot_me:
        #     import matplotlib.pyplot as plt
        # #     # import pdb; pdb.set_trace()
        #     plt.plot(self.time_pts[::2], filtered[0]*np.exp(2j*np.pi * -self.current_freq * self.time_pts[::self.d1], dtype=np.complex64))
        #     plt.plot(self.time_pts[::2], self.reference_r)

        # channel selection filters
        for ct in [1,2]:
            if self.filters[ct] == None:
                continue

            coeffs = self.filters[ct]
            stacked_coeffs = np.concatenate(self.filters[ct])
            out_r = np.empty_like(filtered_r)
            out_i = np.empty_like(filtered_i)
            libipp.filter_records_iir(stacked_coeffs, self.filters[ct][0].size-1, np.ascontiguousarray(filtered_r.astype(np.float32)), filtered_r.shape[-1], num_records, out_r)
            libipp.filter_records_iir(stacked_coeffs, self.filters[ct][0].size-1, np.ascontiguousarray(filtered_i.astype(np.float32)), filtered_i.shape[-1], num_records, out_i)

            # decimate
            if self.decim_factors[ct] > 1:
                filtered_r = np.copy(out_r[:, ::self.decim_factors[ct]], order="C")
                filtered_i = np.copy(out_i[:, ::self.decim_factors[ct]], order="C")
            else:
                filtered_r = out_r
                filtered_i = out_i

        filtered = filtered_r + 1j*filtered_i

        # recover gain from selecting single sideband
        filtered *= 2

        # push to ouptut connectors
        for os in self.source.output_streams:
            await os.push(filtered)

class LibChannelizerFallback(object):
    @staticmethod
    def filter_records_fir(coeffs,
                           num_taps, # ignored
                           decim_factor,
                           recs,
                           record_length, # ignored (uses shape of recs)
                           num_records, # ignored (uses shape of recs)
                           result):
        # split out a, b coefficients
        b = coeffs[:len(coeffs)//2]
        a = coeffs[len(coeffs)//2:]

        filtered_signal = scipy.signal.lfilter(b, a, recs)
        result[:] = np.copy(filtered_signal[:, ::decim_factor], order="C")

    @staticmethod
    def filter_records_iir(coeffs,
                           order, # ignored
                           recs,
                           record_length, # ignored (uses shape of recs)
                           num_records, # ignored (uses shape of recs)
                           result):
        # split out a, b coefficients
        b = coeffs[:len(coeffs)//2]
        a = coeffs[len(coeffs)//2:]

        result[:] = scipy.signal.lfilter(b, a, recs)

if load_fallback:
    libipp = LibChannelizerFallback()
<commit_msg>:tada: Channelizer can now handle partial records<commit_after># Copyright 2016 Raytheon BBN Technologies
#
# 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

__all__ = ['Channelizer']

import os
import platform
from copy import deepcopy

import numpy as np
import scipy.signal

from .filter import Filter
from auspex.parameter import Parameter, IntParameter, FloatParameter
from auspex.stream import  DataStreamDescriptor, InputConnector, OutputConnector
from auspex.log import logger

try:
    # load libchannelizer to access Intel IPP filtering functions
    import numpy.ctypeslib as npct
    from ctypes import c_int, c_size_t
    np_float  = npct.ndpointer(dtype=np.float32, flags='C_CONTIGUOUS')

    libchannelizer_path = os.path.abspath(os.path.join( os.path.dirname(__file__), "libchannelizer"))
    if "Windows" in platform.platform():
        os.environ["PATH"] += ";" + libchannelizer_path
    libipp = npct.load_library("libchannelizer",  libchannelizer_path)
    libipp.filter_records_fir.argtypes = [np_float, c_size_t, c_int, np_float, c_size_t, c_size_t, np_float]
    libipp.filter_records_iir.argtypes = [np_float, c_size_t, np_float, c_size_t, c_size_t, np_float]
    libipp.init()

    load_fallback = False
except:
    logger.warning("Could not load channelizer library; falling back to python methods.")
    load_fallback = True

class Channelizer(Filter):
    """Digital demodulation and filtering to select a particular frequency multiplexed channel. If
    an axis name is supplied to `follow_axis` then the filter will demodulate at the freqency
    `axis_frequency_value - follow_freq_offset` otherwise it will demodulate at `frequency`. Note that
    the filter coefficients are still calculated with respect to the `frequency` paramter, so it should
    be chosen accordingly when `follow_axis` is defined."""

    sink               = InputConnector()
    source             = OutputConnector()
    follow_axis        = Parameter(default="") # Name of the axis to follow
    follow_freq_offset = FloatParameter(default=0.0) # Offset
    decimation_factor  = IntParameter(value_range=(1,100), default=4, snap=1)
    frequency          = FloatParameter(value_range=(-10e9,10e9), increment=1.0e6, default=10e6)
    bandwidth          = FloatParameter(value_range=(0.00, 100e6), increment=0.1e6, default=5e6)

    def __init__(self, frequency=None, bandwidth=None, decimation_factor=None,
                    follow_axis=None, follow_freq_offset=None, **kwargs):
        super(Channelizer, self).__init__(**kwargs)
        if frequency:
            self.frequency.value = frequency
        if bandwidth:
            self.bandwidth.value = bandwidth
        if decimation_factor:
            self.decimation_factor.value = decimation_factor
        if follow_axis:
            self.follow_axis.value = follow_axis
        if follow_freq_offset:
            self.follow_freq_offset.value = follow_freq_offset
        self.quince_parameters = [self.decimation_factor, self.frequency, self.bandwidth]
        self._phase = 0.0

    def final_init(self):
        self.init_filters(self.frequency.value, self.bandwidth.value)

        if self.follow_axis.value is not "":
            self.demod_freqs  = (self.sink.descriptor.expected_tuples(with_metadata=True, as_structured_array=True)[self.follow_axis.value] - self.follow_freq_offset.value)
            self.current_freq = 0
            self.update_references(self.current_freq)
        self.idx = 0

        # For storing carryover if getting uneven buffers
        self.carry = np.zeros(0, dtype=self.output_descriptor.dtype)

    def update_references(self, frequency):
        # store decimated reference for mix down
        # phase_drift = 2j*np.pi*0.5e-6 * (abs(frequency) - 100e6)
        ref = np.exp(2j*np.pi * -frequency * self.time_pts[::self.d1] + 1j*self._phase, dtype=np.complex64)

        self.reference   = ref
        self.reference_r = np.real(ref)
        self.reference_i = np.imag(ref)

    def init_filters(self, frequency, bandwidth):
        # convert bandwidth normalized to Nyquist interval
        n_bandwidth = bandwidth * self.time_step * 2
        n_frequency = frequency * self.time_step * 2

        # arbitrarily decide on three stage filter pipeline
        # 1. first stage decimating filter on real data
        # 2. second stage decimating filter on mixed product to boost n_bandwidth
        # 3. final channel selecting filter at n_bandwidth/2

        # anecdotally don't decimate more than a factor of eight for stability

        self.decim_factors = [1]*3
        self.filters = [None]*3

        # first stage decimating filter
        # maximize first stage decimation:
        #     * minimize subsequent stages time taken
        #     * filter and decimate while signal is still real
        #     * first stage decimation cannot be too large or then 2omega signal from mixing will alias
        self.d1 = 1
        while (self.d1 < 8) and (2*n_frequency <= 0.8/self.d1) and (self.d1 < self.decimation_factor.value):
            self.d1 *= 2
            n_bandwidth *= 2
            n_frequency *= 2

        if self.d1 > 1:
            # create an anti-aliasing filter
            # pass-band to 0.8 * decimation factor; anecdotally single precision needs order <= 4 for stability
            b,a = scipy.signal.cheby1(4, 3, 0.8/self.d1)
            b = np.float32(b)
            a = np.float32(a)
            self.decim_factors[0] = self.d1
            self.filters[0]  = (b,a)

        # store decimated reference for mix down
        self.update_references(frequency)

        # second stage filter to bring n_bandwidth/2 up
        # decimation cannot be too large or will impinge on channel bandwidth (keep n_bandwidth/2 <= 0.8)
        self.d2 = 1
        while (self.d2 < 8) and ((self.d1*self.d2) < self.decimation_factor.value) and (n_bandwidth/2 <= 0.8):
            self.d2 *= 2
            n_bandwidth *= 2
            n_frequency *= 2

        if self.d2 > 1:
            # create an anti-aliasing filter
            # pass-band to 0.8 * decimation factor; anecdotally single precision needs order <= 4 for stability
            b,a = scipy.signal.cheby1(4, 3, 0.8/self.d2)
            b = np.float32(b)
            a = np.float32(a)
            self.decim_factors[1] = self.d2
            self.filters[1]  = (b,a)

        # final channel selection filter
        if n_bandwidth < 0.1:
            raise ValueError("Insufficient decimation to achieve stable filter: {}.".format(n_bandwidth))

        b,a = scipy.signal.cheby1(4, 3, n_bandwidth/2)
        b = np.float32(b)
        a = np.float32(a)
        self.decim_factors[2] = self.decimation_factor.value // (self.d1*self.d2)
        self.filters[2]  = (b,a)

    def update_descriptors(self):
        logger.debug('Updating Channelizer "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor)

        # extract record time sampling
        self.time_pts = self.sink.descriptor.axes[-1].points
        self.record_length = len(self.time_pts)
        self.time_step = self.time_pts[1] - self.time_pts[0]
        logger.debug("Channelizer time_step = {}".format(self.time_step))

        # We will be decimating along a time axis, which is always
        # going to be the last axis given the way we usually take data.
        # TODO: perform this function along a named axis rather than a numbered axis
        # in case something about this changes.

        # update output descriptors
        decimated_descriptor = DataStreamDescriptor()
        decimated_descriptor.axes = self.sink.descriptor.axes[:]
        decimated_descriptor.axes[-1] = deepcopy(self.sink.descriptor.axes[-1])
        decimated_descriptor.axes[-1].points = self.sink.descriptor.axes[-1].points[self.decimation_factor.value-1::self.decimation_factor.value]
        decimated_descriptor.axes[-1].original_points = decimated_descriptor.axes[-1].points
        decimated_descriptor._exp_src = self.sink.descriptor._exp_src
        decimated_descriptor.dtype = np.complex64
        self.output_descriptor = decimated_descriptor
        for os in self.source.output_streams:
            os.set_descriptor(decimated_descriptor)
            if os.end_connector is not None:
                os.end_connector.update_descriptors()

    async def process_data(self, data):

        # Append any data carried from the last run
        if self.carry.size > 0:
            data = np.concatenate((self.carry, data))

        # This is the largest number of records we can handle
        num_records = data.size // self.record_length

        # This is the carryover that we'll store until next round.
        # If nothing is left then reset the carryover.
        remaining_points = data.size % self.record_length
        if remaining_points > 0:
            if num_records > 0:
                self.carry = data[-remaining_points:]
                data = data[:-remaining_points]
            else:
                self.carry = data
        else:
            self.carry = np.zeros(0, dtype=self.output_descriptor.dtype)

        if num_records > 0:
            # The records are processed in parallel after being reshaped here
            reshaped_data = np.reshape(data, (num_records, self.record_length), order="C")

            # Update demodulation frequency if necessary
            if self.follow_axis.value is not "":
                freq = self.demod_freqs[self.idx+1]
                if freq != self.current_freq:
                    self.update_references(freq)
                    self.current_freq = freq

            self.idx += data.size

            # first stage decimating filter
            if self.filters[0] is None:
                filtered = reshaped_data
            else:
                stacked_coeffs = np.concatenate(self.filters[0])
                # filter
                if np.iscomplexobj(reshaped_data):
                    # TODO: compile complex versions of the IPP functions
                    filtered_r = np.empty_like(reshaped_data, dtype=np.float32)
                    filtered_i = np.empty_like(reshaped_data, dtype=np.float32)
                    libipp.filter_records_iir(stacked_coeffs, self.filters[0][0].size-1, np.ascontiguousarray(reshaped_data.real.astype(np.float32)), self.record_length, num_records, filtered_r)
                    libipp.filter_records_iir(stacked_coeffs, self.filters[0][0].size-1, np.ascontiguousarray(reshaped_data.imag.astype(np.float32)), self.record_length, num_records, filtered_i)
                    filtered = filtered_r + 1j*filtered_i
                    # decimate
                    if self.decim_factors[0] > 1:
                        filtered = filtered[:, ::self.decim_factors[0]]
                else:
                    filtered = np.empty_like(reshaped_data)
                    libipp.filter_records_iir(stacked_coeffs, self.filters[0][0].size-1, reshaped_data, self.record_length, num_records, filtered)

                    # decimate
                    if self.decim_factors[0] > 1:
                        filtered = filtered[:, ::self.decim_factors[0]]

            # mix with reference
            # keep real and imaginary separate for filtering below
            if np.iscomplexobj(reshaped_data):
                filtered *= self.reference
                filtered_r = filtered.real
                filtered_i = filtered.imag
            else:
                filtered_r = self.reference_r * filtered
                filtered_i = self.reference_i * filtered

            # channel selection filters
            for ct in [1,2]:
                if self.filters[ct] == None:
                    continue

                coeffs = self.filters[ct]
                stacked_coeffs = np.concatenate(self.filters[ct])
                out_r = np.empty_like(filtered_r)
                out_i = np.empty_like(filtered_i)
                libipp.filter_records_iir(stacked_coeffs, self.filters[ct][0].size-1, np.ascontiguousarray(filtered_r.astype(np.float32)), filtered_r.shape[-1], num_records, out_r)
                libipp.filter_records_iir(stacked_coeffs, self.filters[ct][0].size-1, np.ascontiguousarray(filtered_i.astype(np.float32)), filtered_i.shape[-1], num_records, out_i)

                # decimate
                if self.decim_factors[ct] > 1:
                    filtered_r = np.copy(out_r[:, ::self.decim_factors[ct]], order="C")
                    filtered_i = np.copy(out_i[:, ::self.decim_factors[ct]], order="C")
                else:
                    filtered_r = out_r
                    filtered_i = out_i

            filtered = filtered_r + 1j*filtered_i

            # recover gain from selecting single sideband
            filtered *= 2

            # push to ouptut connectors
            for os in self.source.output_streams:
                await os.push(filtered)

class LibChannelizerFallback(object):
    @staticmethod
    def filter_records_fir(coeffs,
                           num_taps, # ignored
                           decim_factor,
                           recs,
                           record_length, # ignored (uses shape of recs)
                           num_records, # ignored (uses shape of recs)
                           result):
        # split out a, b coefficients
        b = coeffs[:len(coeffs)//2]
        a = coeffs[len(coeffs)//2:]

        filtered_signal = scipy.signal.lfilter(b, a, recs)
        result[:] = np.copy(filtered_signal[:, ::decim_factor], order="C")

    @staticmethod
    def filter_records_iir(coeffs,
                           order, # ignored
                           recs,
                           record_length, # ignored (uses shape of recs)
                           num_records, # ignored (uses shape of recs)
                           result):
        # split out a, b coefficients
        b = coeffs[:len(coeffs)//2]
        a = coeffs[len(coeffs)//2:]

        result[:] = scipy.signal.lfilter(b, a, recs)

if load_fallback:
    libipp = LibChannelizerFallback()
<|endoftext|>


<commit_before>from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm, AdminPasswordChangeForm
from django.contrib.auth.tokens import default_token_generator
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.sites.models import Site, RequestSite
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.utils.http import urlquote, base36_to_int
from django.utils.html import escape
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from django.views.decorators.cache import never_cache
import re

def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME):
    "Displays the login form and handles the login action."
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    if request.method == "POST":
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            # Light security check -- make sure redirect_to isn't garbage.
            if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
                from django.conf import settings
                redirect_to = settings.LOGIN_REDIRECT_URL
            from django.contrib.auth import login
            login(request, form.get_user())
            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()
            return HttpResponseRedirect(redirect_to)
    else:
        form = AuthenticationForm(request)
    request.session.set_test_cookie()
    if Site._meta.installed:
        current_site = Site.objects.get_current()
    else:
        current_site = RequestSite(request)
    return render_to_response(template_name, {
        'form': form,
        redirect_field_name: redirect_to,
        'site_name': current_site.name,
    }, context_instance=RequestContext(request))
login = never_cache(login)

def logout(request, next_page=None, template_name='registration/logged_out.html'):
    "Logs out the user and displays 'You are logged out' message."
    from django.contrib.auth import logout
    logout(request)
    if next_page is None:
        return render_to_response(template_name, {'title': _('Logged out')}, context_instance=RequestContext(request))
    else:
        # Redirect to this page until the session has been cleared.
        return HttpResponseRedirect(next_page or request.path)

def logout_then_login(request, login_url=None):
    "Logs out the user if he is logged in. Then redirects to the log-in page."
    if not login_url:
        from django.conf import settings
        login_url = settings.LOGIN_URL
    return logout(request, login_url)

def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    "Redirects the user to the login page, passing the given 'next' page"
    if not login_url:
        from django.conf import settings
        login_url = settings.LOGIN_URL
    return HttpResponseRedirect('%s?%s=%s' % (login_url, urlquote(redirect_field_name), urlquote(next)))

# 4 views for password reset:
# - password_reset sends the mail
# - password_reset_done shows a success message for the above
# - password_reset_confirm checks the link the user clicked and
#   prompts for a new password
# - password_reset_complete shows a success message for the above

def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
        email_template_name='registration/password_reset_email.html',
        password_reset_form=PasswordResetForm, token_generator=default_token_generator):
    if request.method == "POST":
        form = password_reset_form(request.POST)
        if form.is_valid():
            opts = {}
            opts['use_https'] = request.is_secure()
            opts['token_generator'] = token_generator
            if is_admin_site:
                opts['domain_override'] = request.META['HTTP_HOST']
            else:
                opts['email_template_name'] = email_template_name
                if not Site._meta.installed:
                    opts['domain_override'] = RequestSite(request).domain
            form.save(**opts)
            return HttpResponseRedirect(reverse('django.contrib.auth.views.password_reset_done'))
    else:
        form = password_reset_form()
    return render_to_response(template_name, {
        'form': form,
    }, context_instance=RequestContext(request))

def password_reset_done(request, template_name='registration/password_reset_done.html'):
    return render_to_response(template_name, context_instance=RequestContext(request))

def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html',
                           token_generator=default_token_generator, set_password_form=SetPasswordForm):
    """
    View that checks the hash in a password reset link and presents a
    form for entering a new password.
    """
    assert uidb36 is not None and token is not None # checked by URLconf
    try:
        uid_int = base36_to_int(uidb36)
    except ValueError:
        raise Http404

    user = get_object_or_404(User, id=uid_int)
    context_instance = RequestContext(request)

    if token_generator.check_token(user, token):
        context_instance['validlink'] = True
        if request.method == 'POST':
            form = set_password_form(user, request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect(reverse('django.contrib.auth.views.password_reset_complete'))
        else:
            form = set_password_form(None)
    else:
        context_instance['validlink'] = False
        form = None
    context_instance['form'] = form
    return render_to_response(template_name, context_instance=context_instance)

def password_reset_complete(request, template_name='registration/password_reset_complete.html'):
    return render_to_response(template_name, context_instance=RequestContext(request,
                                                                             {'login_url': settings.LOGIN_URL}))

def password_change(request, template_name='registration/password_change_form.html'):
    if request.method == "POST":
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('django.contrib.auth.views.password_change_done'))
    else:
        form = PasswordChangeForm(request.user)
    return render_to_response(template_name, {
        'form': form,
    }, context_instance=RequestContext(request))
password_change = login_required(password_change)

def password_change_done(request, template_name='registration/password_change_done.html'):
    return render_to_response(template_name, context_instance=RequestContext(request))
<commit_msg>Removed unused and redefined imports.<commit_after>from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm
from django.contrib.auth.tokens import default_token_generator
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.sites.models import Site, RequestSite
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.utils.http import urlquote, base36_to_int
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from django.views.decorators.cache import never_cache

def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME):
    "Displays the login form and handles the login action."
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    if request.method == "POST":
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            # Light security check -- make sure redirect_to isn't garbage.
            if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
                redirect_to = settings.LOGIN_REDIRECT_URL
            from django.contrib.auth import login
            login(request, form.get_user())
            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()
            return HttpResponseRedirect(redirect_to)
    else:
        form = AuthenticationForm(request)
    request.session.set_test_cookie()
    if Site._meta.installed:
        current_site = Site.objects.get_current()
    else:
        current_site = RequestSite(request)
    return render_to_response(template_name, {
        'form': form,
        redirect_field_name: redirect_to,
        'site_name': current_site.name,
    }, context_instance=RequestContext(request))
login = never_cache(login)

def logout(request, next_page=None, template_name='registration/logged_out.html'):
    "Logs out the user and displays 'You are logged out' message."
    from django.contrib.auth import logout
    logout(request)
    if next_page is None:
        return render_to_response(template_name, {'title': _('Logged out')}, context_instance=RequestContext(request))
    else:
        # Redirect to this page until the session has been cleared.
        return HttpResponseRedirect(next_page or request.path)

def logout_then_login(request, login_url=None):
    "Logs out the user if he is logged in. Then redirects to the log-in page."
    if not login_url:
        login_url = settings.LOGIN_URL
    return logout(request, login_url)

def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    "Redirects the user to the login page, passing the given 'next' page"
    if not login_url:
        login_url = settings.LOGIN_URL
    return HttpResponseRedirect('%s?%s=%s' % (login_url, urlquote(redirect_field_name), urlquote(next)))

# 4 views for password reset:
# - password_reset sends the mail
# - password_reset_done shows a success message for the above
# - password_reset_confirm checks the link the user clicked and
#   prompts for a new password
# - password_reset_complete shows a success message for the above

def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
        email_template_name='registration/password_reset_email.html',
        password_reset_form=PasswordResetForm, token_generator=default_token_generator):
    if request.method == "POST":
        form = password_reset_form(request.POST)
        if form.is_valid():
            opts = {}
            opts['use_https'] = request.is_secure()
            opts['token_generator'] = token_generator
            if is_admin_site:
                opts['domain_override'] = request.META['HTTP_HOST']
            else:
                opts['email_template_name'] = email_template_name
                if not Site._meta.installed:
                    opts['domain_override'] = RequestSite(request).domain
            form.save(**opts)
            return HttpResponseRedirect(reverse('django.contrib.auth.views.password_reset_done'))
    else:
        form = password_reset_form()
    return render_to_response(template_name, {
        'form': form,
    }, context_instance=RequestContext(request))

def password_reset_done(request, template_name='registration/password_reset_done.html'):
    return render_to_response(template_name, context_instance=RequestContext(request))

def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html',
                           token_generator=default_token_generator, set_password_form=SetPasswordForm):
    """
    View that checks the hash in a password reset link and presents a
    form for entering a new password.
    """
    assert uidb36 is not None and token is not None # checked by URLconf
    try:
        uid_int = base36_to_int(uidb36)
    except ValueError:
        raise Http404

    user = get_object_or_404(User, id=uid_int)
    context_instance = RequestContext(request)

    if token_generator.check_token(user, token):
        context_instance['validlink'] = True
        if request.method == 'POST':
            form = set_password_form(user, request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect(reverse('django.contrib.auth.views.password_reset_complete'))
        else:
            form = set_password_form(None)
    else:
        context_instance['validlink'] = False
        form = None
    context_instance['form'] = form
    return render_to_response(template_name, context_instance=context_instance)

def password_reset_complete(request, template_name='registration/password_reset_complete.html'):
    return render_to_response(template_name, context_instance=RequestContext(request,
                                                                             {'login_url': settings.LOGIN_URL}))

def password_change(request, template_name='registration/password_change_form.html'):
    if request.method == "POST":
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('django.contrib.auth.views.password_change_done'))
    else:
        form = PasswordChangeForm(request.user)
    return render_to_response(template_name, {
        'form': form,
    }, context_instance=RequestContext(request))
password_change = login_required(password_change)

def password_change_done(request, template_name='registration/password_change_done.html'):
    return render_to_response(template_name, context_instance=RequestContext(request))
<|endoftext|>


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

import conf

from tornado.web import Application, RequestHandler
from src import ui_modules, ui_methods, BoilerUIModule

class AppHandler(RequestHandler):
    def get(self):
        content = '' \
                      'TornadoBoiler is a set of files ' \
                      'which serve me as a base to start ' \
                      'new Tornado projects.' \
                  ''
        self.render('layout.html', raw_content=True,
                    content=content)

app = Application(
    [('/$', AppHandler)],
    debug = conf.debug,
    static_path = './static',
    template_path = './templates',
    ui_modules = [ui_modules],
    ui_methods = [ui_methods],
)

for module in app.ui_modules.values():
    if issubclass(module, BoilerUIModule)
        module.add_handler(app)
<commit_msg>Small syntax error solved on controller.py.<commit_after># -*- coding: UTF-8 -*-

import conf

from tornado.web import Application, RequestHandler
from src import ui_modules, ui_methods, BoilerUIModule

class AppHandler(RequestHandler):
    def get(self):
        content = '' \
                      'TornadoBoiler is a set of files ' \
                      'which serve me as a base to start ' \
                      'new Tornado projects.' \
                  ''
        self.render('layout.html', raw_content=True,
                    content=content)

app = Application(
    [('/$', AppHandler)],
    debug = conf.debug,
    static_path = './static',
    template_path = './templates',
    ui_modules = [ui_modules],
    ui_methods = [ui_methods],
)

for module in app.ui_modules.values():
    if issubclass(module, BoilerUIModule):
        module.add_handler(app)
<|endoftext|>


<commit_before>import sys

from django import http
from django.core import signals
from django.utils.encoding import force_unicode
from django.utils.importlib import import_module
from django.utils.translation import ugettext_lazy as _

class BaseHandler(object):
    # Changes that are always applied to a response (in this order).
    response_fixes = [
        http.fix_location_header,
        http.conditional_content_removal,
        http.fix_IE_for_attach,
        http.fix_IE_for_vary,
    ]

    def __init__(self):
        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None

    def load_middleware(self):
        """
        Populate middleware lists from settings.MIDDLEWARE_CLASSES.

        Must be called after the environment is fixed (see __call__).
        """
        from django.conf import settings
        from django.core import exceptions
        self._view_middleware = []
        self._response_middleware = []
        self._exception_middleware = []

        request_middleware = []
        for middleware_path in settings.MIDDLEWARE_CLASSES:
            try:
                dot = middleware_path.rindex('.')
            except ValueError:
                raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
            mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
            try:
                mod = import_module(mw_module)
            except ImportError, e:
                raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
            try:
                mw_class = getattr(mod, mw_classname)
            except AttributeError:
                raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)

            try:
                mw_instance = mw_class()
            except exceptions.MiddlewareNotUsed:
                continue

            if hasattr(mw_instance, 'process_request'):
                request_middleware.append(mw_instance.process_request)
            if hasattr(mw_instance, 'process_view'):
                self._view_middleware.append(mw_instance.process_view)
            if hasattr(mw_instance, 'process_response'):
                self._response_middleware.insert(0, mw_instance.process_response)
            if hasattr(mw_instance, 'process_exception'):
                self._exception_middleware.insert(0, mw_instance.process_exception)

        # We only assign to this when initialization is complete as it is used
        # as a flag for initialization being complete.
        self._request_middleware = request_middleware

    def get_response(self, request):
        "Returns an HttpResponse object for the given HttpRequest"
        from django.core import exceptions, urlresolvers
        from django.conf import settings

        # Apply request middleware
        for middleware_method in self._request_middleware:
            response = middleware_method(request)
            if response:
                return response

        # Get urlconf from request object, if available.  Otherwise use default.
        urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)

        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
        try:
            callback, callback_args, callback_kwargs = resolver.resolve(
                    request.path_info)

            # Apply view middleware
            for middleware_method in self._view_middleware:
                response = middleware_method(request, callback, callback_args, callback_kwargs)
                if response:
                    return response

            try:
                response = callback(request, *callback_args, **callback_kwargs)
            except Exception, e:
                # If the view raised an exception, run it through exception
                # middleware, and if the exception middleware returns a
                # response, use that. Otherwise, reraise the exception.
                for middleware_method in self._exception_middleware:
                    response = middleware_method(request, e)
                    if response:
                        return response
                raise

            # Complain if the view returned None (a common error).
            if response is None:
                try:
                    view_name = callback.func_name # If it's a function
                except AttributeError:
                    view_name = callback.__class__.__name__ + '.__call__' # If it's a class
                raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)

            return response
        except http.Http404, e:
            if settings.DEBUG:
                from django.views import debug
                return debug.technical_404_response(request, e)
            else:
                try:
                    callback, param_dict = resolver.resolve404()
                    return callback(request, **param_dict)
                except:
                    try:
                        return self.handle_uncaught_exception(request, resolver, sys.exc_info())
                    finally:
                        receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
        except exceptions.PermissionDenied:
            return http.HttpResponseForbidden('
%s
' % _("Permission denied"))
        except SystemExit:
            # Allow sys.exit() to actually exit. See tickets #1023 and #4701
            raise
        except: # Handle everything else, including SuspiciousOperation, etc.
            # Get the exception info now, in case another exception is thrown later.
            exc_info = sys.exc_info()
            receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
            return self.handle_uncaught_exception(request, resolver, exc_info)

    def handle_uncaught_exception(self, request, resolver, exc_info):
        """
        Processing for any otherwise uncaught exceptions (those that will
        generate HTTP 500 responses). Can be overridden by subclasses who want
        customised 500 handling.

        Be *very* careful when overriding this because the error could be
        caused by anything, so assuming something like the database is always
        available would be an error.
        """
        from django.conf import settings
        from django.core.mail import mail_admins

        if settings.DEBUG_PROPAGATE_EXCEPTIONS:
            raise

        if settings.DEBUG:
            from django.views import debug
            return debug.technical_500_response(request, *exc_info)

        # When DEBUG is False, send an error message to the admins.
        subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
        try:
            request_repr = repr(request)
        except:
            request_repr = "Request repr() unavailable"
        message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
        mail_admins(subject, message, fail_silently=True)
        # Return an HttpResponse that displays a friendly error message.
        callback, param_dict = resolver.resolve500()
        return callback(request, **param_dict)

    def _get_traceback(self, exc_info=None):
        "Helper function to return the traceback as a string"
        import traceback
        return '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info())))

    def apply_response_fixes(self, request, response):
        """
        Applies each of the functions in self.response_fixes to the request and
        response, modifying the response in the process. Returns the new
        response.
        """
        for func in self.response_fixes:
            response = func(request, response)
        return response

def get_script_name(environ):
    """
    Returns the equivalent of the HTTP request's SCRIPT_NAME environment
    variable. If Apache mod_rewrite has been used, returns what would have been
    the script name prior to any rewriting (so it's the script name as seen
    from the client's perspective), unless DJANGO_USE_POST_REWRITE is set (to
    anything).
    """
    from django.conf import settings
    if settings.FORCE_SCRIPT_NAME is not None:
        return force_unicode(settings.FORCE_SCRIPT_NAME)

    # If Apache's mod_rewrite had a whack at the URL, Apache set either
    # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any
    # rewrites. Unfortunately not every webserver (lighttpd!) passes this
    # information through all the time, so FORCE_SCRIPT_NAME, above, is still
    # needed.
    script_url = environ.get('SCRIPT_URL', u'')
    if not script_url:
        script_url = environ.get('REDIRECT_URL', u'')
    if script_url:
        return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
    return force_unicode(environ.get('SCRIPT_NAME', u''))

<commit_msg>Reverted [10346] because it effectively breaks USE_I18N by forcing import of translation before settings are ready.<commit_after>import sys

from django import http
from django.core import signals
from django.utils.encoding import force_unicode
from django.utils.importlib import import_module

class BaseHandler(object):
    # Changes that are always applied to a response (in this order).
    response_fixes = [
        http.fix_location_header,
        http.conditional_content_removal,
        http.fix_IE_for_attach,
        http.fix_IE_for_vary,
    ]

    def __init__(self):
        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None

    def load_middleware(self):
        """
        Populate middleware lists from settings.MIDDLEWARE_CLASSES.

        Must be called after the environment is fixed (see __call__).
        """
        from django.conf import settings
        from django.core import exceptions
        self._view_middleware = []
        self._response_middleware = []
        self._exception_middleware = []

        request_middleware = []
        for middleware_path in settings.MIDDLEWARE_CLASSES:
            try:
                dot = middleware_path.rindex('.')
            except ValueError:
                raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
            mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
            try:
                mod = import_module(mw_module)
            except ImportError, e:
                raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
            try:
                mw_class = getattr(mod, mw_classname)
            except AttributeError:
                raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)

            try:
                mw_instance = mw_class()
            except exceptions.MiddlewareNotUsed:
                continue

            if hasattr(mw_instance, 'process_request'):
                request_middleware.append(mw_instance.process_request)
            if hasattr(mw_instance, 'process_view'):
                self._view_middleware.append(mw_instance.process_view)
            if hasattr(mw_instance, 'process_response'):
                self._response_middleware.insert(0, mw_instance.process_response)
            if hasattr(mw_instance, 'process_exception'):
                self._exception_middleware.insert(0, mw_instance.process_exception)

        # We only assign to this when initialization is complete as it is used
        # as a flag for initialization being complete.
        self._request_middleware = request_middleware

    def get_response(self, request):
        "Returns an HttpResponse object for the given HttpRequest"
        from django.core import exceptions, urlresolvers
        from django.conf import settings

        # Apply request middleware
        for middleware_method in self._request_middleware:
            response = middleware_method(request)
            if response:
                return response

        # Get urlconf from request object, if available.  Otherwise use default.
        urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)

        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
        try:
            callback, callback_args, callback_kwargs = resolver.resolve(
                    request.path_info)

            # Apply view middleware
            for middleware_method in self._view_middleware:
                response = middleware_method(request, callback, callback_args, callback_kwargs)
                if response:
                    return response

            try:
                response = callback(request, *callback_args, **callback_kwargs)
            except Exception, e:
                # If the view raised an exception, run it through exception
                # middleware, and if the exception middleware returns a
                # response, use that. Otherwise, reraise the exception.
                for middleware_method in self._exception_middleware:
                    response = middleware_method(request, e)
                    if response:
                        return response
                raise

            # Complain if the view returned None (a common error).
            if response is None:
                try:
                    view_name = callback.func_name # If it's a function
                except AttributeError:
                    view_name = callback.__class__.__name__ + '.__call__' # If it's a class
                raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)

            return response
        except http.Http404, e:
            if settings.DEBUG:
                from django.views import debug
                return debug.technical_404_response(request, e)
            else:
                try:
                    callback, param_dict = resolver.resolve404()
                    return callback(request, **param_dict)
                except:
                    try:
                        return self.handle_uncaught_exception(request, resolver, sys.exc_info())
                    finally:
                        receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
        except exceptions.PermissionDenied:
            return http.HttpResponseForbidden('
Permission denied
')
        except SystemExit:
            # Allow sys.exit() to actually exit. See tickets #1023 and #4701
            raise
        except: # Handle everything else, including SuspiciousOperation, etc.
            # Get the exception info now, in case another exception is thrown later.
            exc_info = sys.exc_info()
            receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
            return self.handle_uncaught_exception(request, resolver, exc_info)

    def handle_uncaught_exception(self, request, resolver, exc_info):
        """
        Processing for any otherwise uncaught exceptions (those that will
        generate HTTP 500 responses). Can be overridden by subclasses who want
        customised 500 handling.

        Be *very* careful when overriding this because the error could be
        caused by anything, so assuming something like the database is always
        available would be an error.
        """
        from django.conf import settings
        from django.core.mail import mail_admins

        if settings.DEBUG_PROPAGATE_EXCEPTIONS:
            raise

        if settings.DEBUG:
            from django.views import debug
            return debug.technical_500_response(request, *exc_info)

        # When DEBUG is False, send an error message to the admins.
        subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
        try:
            request_repr = repr(request)
        except:
            request_repr = "Request repr() unavailable"
        message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
        mail_admins(subject, message, fail_silently=True)
        # Return an HttpResponse that displays a friendly error message.
        callback, param_dict = resolver.resolve500()
        return callback(request, **param_dict)

    def _get_traceback(self, exc_info=None):
        "Helper function to return the traceback as a string"
        import traceback
        return '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info())))

    def apply_response_fixes(self, request, response):
        """
        Applies each of the functions in self.response_fixes to the request and
        response, modifying the response in the process. Returns the new
        response.
        """
        for func in self.response_fixes:
            response = func(request, response)
        return response

def get_script_name(environ):
    """
    Returns the equivalent of the HTTP request's SCRIPT_NAME environment
    variable. If Apache mod_rewrite has been used, returns what would have been
    the script name prior to any rewriting (so it's the script name as seen
    from the client's perspective), unless DJANGO_USE_POST_REWRITE is set (to
    anything).
    """
    from django.conf import settings
    if settings.FORCE_SCRIPT_NAME is not None:
        return force_unicode(settings.FORCE_SCRIPT_NAME)

    # If Apache's mod_rewrite had a whack at the URL, Apache set either
    # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any
    # rewrites. Unfortunately not every webserver (lighttpd!) passes this
    # information through all the time, so FORCE_SCRIPT_NAME, above, is still
    # needed.
    script_url = environ.get('SCRIPT_URL', u'')
    if not script_url:
        script_url = environ.get('REDIRECT_URL', u'')
    if script_url:
        return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
    return force_unicode(environ.get('SCRIPT_NAME', u''))

<|endoftext|>


<commit_before>"""
Copyright (c) 2013-2014 Heiko Strathmann
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 *
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 *
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the author.
"""

from numpy import zeros, ones, asarray
import numpy
from numpy.random import rand, randint
import unittest

from kameleon_mcmc.distribution.DiscreteRandomWalkProposal import DiscreteRandomWalkProposal
from kameleon_mcmc.distribution.Distribution import Sample

class DiscreteRandomWalkProposalUnitTest(unittest.TestCase):
    def test_contructor_wrong_mu_type_float(self):
        mu = 0
        spread = 1.
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_mu_type_none(self):
        mu = None
        spread = 1.
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_mu_dim_too_large(self):
        mu = zeros((1, 2), dtype=numpy.bool8)
        spread = 1.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_mu_dimension_0(self):
        mu = zeros(0, dtype=numpy.bool8)
        spread = 1.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_type_int(self):
        mu = zeros(2, dtype=numpy.bool8)
        spread = 1
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_type_none(self):
        mu = zeros(2, dtype=numpy.bool8)
        spread = None
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_range_0(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = 0.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_range_1(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = 1.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_correct_mu(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertTrue(mu is dist.mu)

    def test_contructor_correct_spread(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertEqual(spread, dist.spread)

#
    def test_sample_wrong_n_sameller_zero(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(ValueError, dist.sample, -1)

    def test_sample_wrong_n_type_none(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.sample, None)

    def test_sample_wrong_n_type_float(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.sample, float(1.))

    def test_sample_type(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        s = dist.sample(1)
        self.assertTrue(isinstance(s, Sample))

    def test_sample_samples_dtype(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        s = dist.sample(1)
        self.assertEqual(s.samples.dtype, numpy.bool8)

    def test_sample_dim(self):
        n = 3
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        s = dist.sample(n)
        self.assertEqual(s.samples.shape, (n, d))

    def test_sample_many_no_checks(self):
        num_runs = 1000
        for _ in range(num_runs):
            n = randint(1, 10)
            d = randint(1, 10)
            mu = randint(0, 2, d).astype(numpy.bool8)
            spread = rand()
            dist = DiscreteRandomWalkProposal(mu, spread)
            dist.sample(n)
#
    def test_log_pdf_wrong_type_none(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, None)

    def test_log_pdf_wrong_type_float(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, float(1.))

    def test_log_pdf_wrong_array_dimension_1(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, zeros(1))

    def test_log_pdf_wrong_array_dimension_3(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, zeros(3))

    def test_log_pdf_wrong_dimension(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(ValueError, dist.log_pdf, zeros((1, 3)))

    def test_log_pdf_type(self):
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[0]], dtype=numpy.bool8)
        self.assertEqual(type(dist.log_pdf(X)), numpy.ndarray)

    def test_log_pdf_returned_array_dimension_1d_X(self):
        n = 1
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[0]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_returned_array_dimension_2d_X(self):
        n = 1
        mu = asarray([0, 0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[0, 1]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_returned_array_dimension_multiple_X_1d(self):
        n = 2
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1], [0]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_returned_array_dimension_multiple_X_2d(self):
        n = 2
        mu = asarray([0, 1], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1, 0], [0, 0]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

if __name__ == "__main__":
    unittest.main()
<commit_msg>prepared a couple of (yet failing) tests for log_pdf results<commit_after>"""
Copyright (c) 2013-2014 Heiko Strathmann
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 *
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 *
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the author.
"""

from numpy import zeros, ones, asarray
import numpy
from numpy.linalg import norm
from numpy.random import rand, randint
import unittest

from kameleon_mcmc.distribution.DiscreteRandomWalkProposal import DiscreteRandomWalkProposal
from kameleon_mcmc.distribution.Distribution import Sample

class DiscreteRandomWalkProposalUnitTest(unittest.TestCase):
    def test_contructor_wrong_mu_type_float(self):
        mu = 0
        spread = 1.
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_mu_type_none(self):
        mu = None
        spread = 1.
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_mu_dim_too_large(self):
        mu = zeros((1, 2), dtype=numpy.bool8)
        spread = 1.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_mu_dimension_0(self):
        mu = zeros(0, dtype=numpy.bool8)
        spread = 1.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_type_int(self):
        mu = zeros(2, dtype=numpy.bool8)
        spread = 1
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_type_none(self):
        mu = zeros(2, dtype=numpy.bool8)
        spread = None
        self.assertRaises(TypeError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_range_0(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = 0.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_wrong_spread_range_1(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = 1.
        self.assertRaises(ValueError, DiscreteRandomWalkProposal, mu, spread)

    def test_contructor_correct_mu(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertTrue(mu is dist.mu)

    def test_contructor_correct_spread(self):
        mu = ones(2, dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertEqual(spread, dist.spread)

#
    def test_sample_wrong_n_sameller_zero(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(ValueError, dist.sample, -1)

    def test_sample_wrong_n_type_none(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.sample, None)

    def test_sample_wrong_n_type_float(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.sample, float(1.))

    def test_sample_type(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        s = dist.sample(1)
        self.assertTrue(isinstance(s, Sample))

    def test_sample_samples_dtype(self):
        mu = randint(0, 2, 10).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        s = dist.sample(1)
        self.assertEqual(s.samples.dtype, numpy.bool8)

    def test_sample_dim(self):
        n = 3
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        s = dist.sample(n)
        self.assertEqual(s.samples.shape, (n, d))

    def test_sample_many_no_checks(self):
        num_runs = 1000
        for _ in range(num_runs):
            n = randint(1, 10)
            d = randint(1, 10)
            mu = randint(0, 2, d).astype(numpy.bool8)
            spread = rand()
            dist = DiscreteRandomWalkProposal(mu, spread)
            dist.sample(n)
#
    def test_log_pdf_wrong_type_none(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, None)

    def test_log_pdf_wrong_type_float(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, float(1.))

    def test_log_pdf_wrong_array_dimension_1(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, zeros(1))

    def test_log_pdf_wrong_array_dimension_3(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(TypeError, dist.log_pdf, zeros(3))

    def test_log_pdf_wrong_dimension(self):
        d = 2
        mu = randint(0, 2, d).astype(numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        self.assertRaises(ValueError, dist.log_pdf, zeros((1, 3)))

    def test_log_pdf_type(self):
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[0]], dtype=numpy.bool8)
        self.assertEqual(type(dist.log_pdf(X)), numpy.ndarray)

    def test_log_pdf_returned_array_dimension_1d_X(self):
        n = 1
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[0]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_returned_array_dimension_2d_X(self):
        n = 1
        mu = asarray([0, 0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[0, 1]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_returned_array_dimension_multiple_X_1d(self):
        n = 2
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1], [0]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_returned_array_dimension_multiple_X_2d(self):
        n = 2
        mu = asarray([0, 1], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1, 0], [0, 0]], dtype=numpy.bool8)
        self.assertEqual(dist.log_pdf(X).shape, (n,))

    def test_log_pdf_1n_1d(self):
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1]], dtype=numpy.bool8)
        result = dist.log_pdf(X)
        expected = zeros(1) + numpy.nan
        self.assertAlmostEqual(norm(result - expected), 0)
        #
    def test_log_pdf_2n_1d(self):
        mu = asarray([0], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1], [0]], dtype=numpy.bool8)
        result = dist.log_pdf(X)
        expected = zeros(2) + numpy.nan
        self.assertAlmostEqual(norm(result - expected), 0)

    def test_log_pdf_1n_2d(self):
        mu = asarray([0, 1], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1, 1]], dtype=numpy.bool8)
        result = dist.log_pdf(X)
        expected = zeros(1) + numpy.nan
        self.assertAlmostEqual(norm(result - expected), 0)

    def test_log_pdf_2n_2d(self):
        mu = asarray([0, 1], dtype=numpy.bool8)
        spread = .5
        dist = DiscreteRandomWalkProposal(mu, spread)
        X = asarray([[1, 1], [0, 1]], dtype=numpy.bool8)
        result = dist.log_pdf(X)
        expected = zeros(2) + numpy.nan
        self.assertAlmostEqual(norm(result - expected), 0)

if __name__ == "__main__":
    unittest.main()
<|endoftext|>


<commit_before>import numpy as np
import warnings
from time import time
import logging
import traceback
import copy

log = logging.getLogger(__name__)

try:
    from scipy.integrate import ode
except ImportError as e:
    warnings.warn("Submodule 'ode_wrapper' will not work. Reason: {}.".format(e))

class Dummy_c(object):
    def __init__(self):
        self.value = 0
        pass

def complex_to_real(vc):
    return np.hstack([np.real(vc), np.imag(vc)])

def real_to_complex(vr):
    n = len(vr)//2
    return vr[:n] + 1j*vr[n:]

def wrap_complex_intgeration(f_complex):
    """
    if f: R x C^n -> C^n
    then this functions returns the real equivalent
    f_prime R x R^n x R^n -> R^n x R^n

    such that a complex vector
        cc = [vc_1, ... vc_n]
    translates to
        cr = [RE(vc_1), ... RE(vc_n), IM(vc_1), ... IM(vc_n)]
    """
    def f_real(t, yr):
        return complex_to_real( f_complex(t, real_to_complex(yr)) )

    return f_real

def timed_f(f, time_as_list):
    def new_f(t, x):
        t0 = time()
        res = f(t, x)
        t1 = time()
        time_as_list[0] += t1-t0
        return res
    return new_f

def integrate_cplx(c, t0, t1, N, f, args, x0, integrator, res_dim=None, x_to_res=None, scale_function=None, **kwargs):
    f_partial_complex = lambda t, x: f(t, x, *args)
    if integrator == 'zvode':
        # define complex derivative
        f_ = f_partial_complex
        x0_ = x0
    elif (integrator == 'vode') | (integrator == 'lsoda') | (integrator == 'dopri5') | (integrator == 'dop853'):
        # define real derivative (separation for real and imaginary part)
        f_ = lambda t, x: wrap_complex_intgeration(f_partial_complex)(t, x)
        x0_ = complex_to_real(x0)
        log.warning("PERFORMANCE WARNING, avoid using 'vode' or 'lsoda' for complex ode's")
    else:
        raise RuntimeError("unknown integrator '{}'".format(integrator))

    time_as_list = [0.]

    f__ = timed_f(f_, time_as_list)

    r = ode(f__)

    if (integrator == 'dopri5') | (integrator == 'dop853'):
        if 'order' in kwargs:
            del kwargs['order']

    kws = list(kwargs.keys())
    for kw in kws:
        if kwargs[kw] is None:
            del kwargs[kw]

    r.set_integrator(integrator, **kwargs)

    # x0_ might be the mapping from C to R^2
    r.set_initial_value(x0_, t0)

    t = np.linspace(t0, t1, N)

    if res_dim is None:
        res_dim = (len(x0), )
        res_list_len = None
    else:
        try:
            res_list_len = len(res_dim)
            assert res_list_len == len(x_to_res)
        except TypeError:
            res_list_len = None

    if x_to_res is None:
        x_to_res = lambda t_, x_: x_

    # the usual case with only one result type
    if res_list_len is None:

        # complex array for result
        x = np.empty(shape=(N,) + res_dim, dtype=np.complex128)
        x[0] = x_to_res(t0, x0)

    #         print(args.eta._Z)

        t_int = 0
        t_conv = 0

        i = 1
        with warnings.catch_warnings():
            warnings.filterwarnings('error')
            try:
                while i < N:
                    _t = time()
                    r.integrate(t[i])
                    t_int += (time()-_t)

                    if not r.successful():
                        msg = "INTEGRATION WARNING: NOT successful!"
                        log.warning(msg)
                        raise Warning(msg)

                    _t = time()
                    r_y = copy.copy(r.y)
                    if scale_function:
                        r_y = scale_function(r_y)

                    if integrator == 'zvode':
                        # complex integration -> yields complex values
                        x[i] = x_to_res(r.t, r_y)
                    else:
                        # real integration -> mapping from R^2 to C needed
                        x[i] = x_to_res(r.t, real_to_complex(r_y))
                    t_conv += (time()-_t)

                    if abs(t[i]-r.t) > 1e-13:
                        msg = "INTEGRATION WARNING: time mismatch (diff at step {}: {:.3e})".format(i, abs(t[i]-r.t))
                        log.warning(msg)
                        raise Warning(msg)
                    t[i] = r.t
                    c.value = i

                    if scale_function:
                        del r
                        r = ode(f__)
                        r.set_integrator(integrator, **kwargs)
                        r.set_initial_value(y=r_y, t=t[i])

                    i += 1

            except Exception as e:
                trb = traceback.format_exc()
                return t[:i], x[:i], (e, trb)

    # having to compute multiple result types
    else:
        # complex array for result
        x = []
        for a in range(res_list_len):
            x.append(np.empty(shape=(N,) + res_dim[a], dtype=np.complex128))
            x[-1][0] = x_to_res[a](t0, x0)

    #         print(args.eta._Z)

        t_int = 0
        t_conv = 0

        i = 1
        with warnings.catch_warnings():
            warnings.filterwarnings('error')
            try:
                while r.successful() and i < N:
                    _t = time()
                    r.integrate(t[i])
                    t_int += (time()-_t)

                    if not r.successful():
                        msg = "INTEGRATION WARNING: NOT successful!"
                        log.warning(msg)
                        raise Warning(msg)

                    _t = time()
                    r_y = copy.copy(r.y)
                    if integrator == 'zvode':
                        # complex integration -> yields complex values
                        for a in range(res_list_len):
                            x[a][i] = x_to_res[a](r.t, r_y)
                    else:
                        # real integration -> mapping from R^2 to C needed
                        for a in range(res_list_len):
                            x[a][i] = x_to_res[a](r.t, real_to_complex(r_y))
                    t_conv += (time()-_t)
                    if abs(t[i]-r.t) > 1e-13:
                        msg = "INTEGRATION WARNING: time mismatch (diff at step {}: {:.3e})".format(i, abs(t[i]-r.t))
                        log.warning(msg)
                        raise Warning(msg)
                    t[i] = r.t
                    c.value = i

                    if scale_function:
                        del r
                        r = ode(f__)
                        r.set_integrator(integrator, **kwargs)
                        r.set_initial_value(y=scale_function(copy.copy(r_y)), t=t[i])

                    i += 1

            except Exception as e:
                trb = traceback.format_exc()
                return t[:i], [xa[:i] for xa in x], (e, trb)

    log.info("integration summary\n"+
             "integration     time {:.2g}s ({:.2%})\n".format(t_int, t_int / (t_int + t_conv))+
             "    f_dot eval       {:.2g}s ({:.2%})\n".format(time_as_list[0], time_as_list[0] / (t_int + t_conv))+
             "data conversion time {:.2g}s ({:.2%})\n".format(t_conv, t_conv / (t_int + t_conv)))
    return t, x, None

def integrate_real(c, t0, t1, N, f, args, x0, integrator, verbose=0, res_dim=None, x_to_res=None, **kwargs):
    f_partial = lambda t, x: f(t, x, *args)
    if integrator == 'zvode':
        # define complex derivative
        raise RuntimeError("'zvode' can not be used for real integration")
    elif (integrator == 'vode') | (integrator == 'lsoda'):
        pass
    else:
        raise RuntimeError("unknown integrator '{}'".format(integrator))

    r = ode(f_partial)

    kws = list(kwargs.keys())
    for kw in kws:
        if kwargs[kw] is None:
            del kwargs[kw]

    r.set_integrator(integrator, **kwargs)

    # x0_ might be the mapping from C to R^2
    r.set_initial_value(x0, t0)

    t = np.linspace(t0, t1, N)

    if res_dim is None:
        res_dim = (len(x0), )

    if x_to_res is None:
        x_to_res = lambda t_, x_: x_

    # float array for result
    x = np.empty(shape=(N,) + res_dim, dtype=np.float64)
    x[0] = x_to_res(t0, x0)

    t_int = 0
    t_conv = 0

    i = 1
    with warnings.catch_warnings():
        warnings.filterwarnings('error')
        try:
            while r.successful() and i < N:
                _t = time()
                r.integrate(t[i])
                t_int += (time()-_t)

                _t = time()
                x[i] = x_to_res(r.t, r.y)
                t_conv += (time()-_t)
                if abs(t[i]-r.t) > 1e-13:
                    msg = "INTEGRATION WARNING: time mismatch (diff at step {}: {:.3e})".format(i, abs(t[i]-r.t))
                    log.warning(msg)
                    raise Warning(msg)
                t[i] = r.t
                c.value = i
                i += 1

            if not r.successful():
                msg = "INTEGRATION WARNING: NOT successful!"
                log.warning(msg)
                raise Warning(msg)
        except Exception as e:
            trb = traceback.format_exc()
            return t[:i], x[:i], (e, trb)

    log.info("integration summary\n"+
             "integration     time {:.2g}s ({:.2%})\n".format(t_int, t_int / (t_int + t_conv))+
             "data conversion time {:.2g}s ({:.2%})\n".format(t_conv, t_conv / (t_int + t_conv)))

    return t, x, None
<commit_msg>added scale_condition<commit_after>import numpy as np
import warnings
from time import time
import logging
import traceback
import copy

log = logging.getLogger(__name__)

try:
    from scipy.integrate import ode
except ImportError as e:
    warnings.warn("Submodule 'ode_wrapper' will not work. Reason: {}.".format(e))

class Dummy_c(object):
    def __init__(self):
        self.value = 0
        pass

def complex_to_real(vc):
    return np.hstack([np.real(vc), np.imag(vc)])

def real_to_complex(vr):
    n = len(vr)//2
    return vr[:n] + 1j*vr[n:]

def wrap_complex_intgeration(f_complex):
    """
    if f: R x C^n -> C^n
    then this functions returns the real equivalent
    f_prime R x R^n x R^n -> R^n x R^n

    such that a complex vector
        cc = [vc_1, ... vc_n]
    translates to
        cr = [RE(vc_1), ... RE(vc_n), IM(vc_1), ... IM(vc_n)]
    """
    def f_real(t, yr):
        return complex_to_real( f_complex(t, real_to_complex(yr)) )

    return f_real

def timed_f(f, time_as_list):
    def new_f(t, x):
        t0 = time()
        res = f(t, x)
        t1 = time()
        time_as_list[0] += t1-t0
        return res
    return new_f

def integrate_cplx(c, t0, t1, N, f, args, x0, integrator, res_dim=None, x_to_res=None,
                   scale_function=None, scale_condition=None, **kwargs):
    f_partial_complex = lambda t, x: f(t, x, *args)
    if integrator == 'zvode':
        # define complex derivative
        f_ = f_partial_complex
        x0_ = x0
    elif (integrator == 'vode') | (integrator == 'lsoda') | (integrator == 'dopri5') | (integrator == 'dop853'):
        # define real derivative (separation for real and imaginary part)
        f_ = lambda t, x: wrap_complex_intgeration(f_partial_complex)(t, x)
        x0_ = complex_to_real(x0)
        log.warning("PERFORMANCE WARNING, avoid using 'vode' or 'lsoda' for complex ode's")
    else:
        raise RuntimeError("unknown integrator '{}'".format(integrator))

    time_as_list = [0.]

    f__ = timed_f(f_, time_as_list)

    r = ode(f__)

    if (integrator == 'dopri5') | (integrator == 'dop853'):
        if 'order' in kwargs:
            del kwargs['order']

    kws = list(kwargs.keys())
    for kw in kws:
        if kwargs[kw] is None:
            del kwargs[kw]

    r.set_integrator(integrator, **kwargs)

    # x0_ might be the mapping from C to R^2
    r.set_initial_value(x0_, t0)

    t = np.linspace(t0, t1, N)

    if res_dim is None:
        res_dim = (len(x0), )
        res_list_len = None
    else:
        try:
            res_list_len = len(res_dim)
            assert res_list_len == len(x_to_res)
        except TypeError:
            res_list_len = None

    if x_to_res is None:
        x_to_res = lambda t_, x_: x_

    # the usual case with only one result type
    if res_list_len is None:

        # complex array for result
        x = np.empty(shape=(N,) + res_dim, dtype=np.complex128)
        x[0] = x_to_res(t0, x0)

    #         print(args.eta._Z)

        t_int = 0
        t_conv = 0

        i = 1
        with warnings.catch_warnings():
            warnings.filterwarnings('error')
            try:
                while i < N:
                    _t = time()
                    r.integrate(t[i])
                    t_int += (time()-_t)

                    if not r.successful():
                        msg = "INTEGRATION WARNING: NOT successful!"
                        log.warning(msg)
                        raise Warning(msg)

                    _t = time()
                    r_y = copy.copy(r.y)
                    is_scaled = False
                    if scale_condition:
                        if scale_condition(r_y):
                            r_y = scale_function(r_y)
                            is_scaled = True

                    if integrator == 'zvode':
                        # complex integration -> yields complex values
                        x[i] = x_to_res(r.t, r_y)
                    else:
                        # real integration -> mapping from R^2 to C needed
                        x[i] = x_to_res(r.t, real_to_complex(r_y))
                    t_conv += (time()-_t)

                    if abs(t[i]-r.t) > 1e-13:
                        msg = "INTEGRATION WARNING: time mismatch (diff at step {}: {:.3e})".format(i, abs(t[i]-r.t))
                        log.warning(msg)
                        raise Warning(msg)
                    t[i] = r.t
                    c.value = i

                    if is_scaled:
                        del r
                        r = ode(f__)
                        r.set_integrator(integrator, **kwargs)
                        r.set_initial_value(y=r_y, t=t[i])

                    i += 1

            except Exception as e:
                trb = traceback.format_exc()
                return t[:i], x[:i], (e, trb)

    # having to compute multiple result types
    else:
        # complex array for result
        x = []
        for a in range(res_list_len):
            x.append(np.empty(shape=(N,) + res_dim[a], dtype=np.complex128))
            x[-1][0] = x_to_res[a](t0, x0)

    #         print(args.eta._Z)

        t_int = 0
        t_conv = 0

        i = 1
        with warnings.catch_warnings():
            warnings.filterwarnings('error')
            try:
                while r.successful() and i < N:
                    _t = time()
                    r.integrate(t[i])
                    t_int += (time()-_t)

                    if not r.successful():
                        msg = "INTEGRATION WARNING: NOT successful!"
                        log.warning(msg)
                        raise Warning(msg)

                    _t = time()
                    r_y = copy.copy(r.y)
                    is_scaled = False
                    if scale_condition:
                        if scale_condition(r_y):
                            r_y = scale_function(r_y)
                            is_scaled = True
                    if integrator == 'zvode':
                        # complex integration -> yields complex values
                        for a in range(res_list_len):
                            x[a][i] = x_to_res[a](r.t, r_y)
                    else:
                        # real integration -> mapping from R^2 to C needed
                        for a in range(res_list_len):
                            x[a][i] = x_to_res[a](r.t, real_to_complex(r_y))
                    t_conv += (time()-_t)
                    if abs(t[i]-r.t) > 1e-13:
                        msg = "INTEGRATION WARNING: time mismatch (diff at step {}: {:.3e})".format(i, abs(t[i]-r.t))
                        log.warning(msg)
                        raise Warning(msg)
                    t[i] = r.t
                    c.value = i

                    if is_scaled:
                        del r
                        r = ode(f__)
                        r.set_integrator(integrator, **kwargs)
                        r.set_initial_value(y=scale_function(copy.copy(r_y)), t=t[i])

                    i += 1

            except Exception as e:
                trb = traceback.format_exc()
                return t[:i], [xa[:i] for xa in x], (e, trb)

    log.info("integration summary\n"+
             "integration     time {:.2g}s ({:.2%})\n".format(t_int, t_int / (t_int + t_conv))+
             "    f_dot eval       {:.2g}s ({:.2%})\n".format(time_as_list[0], time_as_list[0] / (t_int + t_conv))+
             "data conversion time {:.2g}s ({:.2%})\n".format(t_conv, t_conv / (t_int + t_conv)))
    return t, x, None

def integrate_real(c, t0, t1, N, f, args, x0, integrator, verbose=0, res_dim=None, x_to_res=None, **kwargs):
    f_partial = lambda t, x: f(t, x, *args)
    if integrator == 'zvode':
        # define complex derivative
        raise RuntimeError("'zvode' can not be used for real integration")
    elif (integrator == 'vode') | (integrator == 'lsoda'):
        pass
    else:
        raise RuntimeError("unknown integrator '{}'".format(integrator))

    r = ode(f_partial)

    kws = list(kwargs.keys())
    for kw in kws:
        if kwargs[kw] is None:
            del kwargs[kw]

    r.set_integrator(integrator, **kwargs)

    # x0_ might be the mapping from C to R^2
    r.set_initial_value(x0, t0)

    t = np.linspace(t0, t1, N)

    if res_dim is None:
        res_dim = (len(x0), )

    if x_to_res is None:
        x_to_res = lambda t_, x_: x_

    # float array for result
    x = np.empty(shape=(N,) + res_dim, dtype=np.float64)
    x[0] = x_to_res(t0, x0)

    t_int = 0
    t_conv = 0

    i = 1
    with warnings.catch_warnings():
        warnings.filterwarnings('error')
        try:
            while r.successful() and i < N:
                _t = time()
                r.integrate(t[i])
                t_int += (time()-_t)

                _t = time()
                x[i] = x_to_res(r.t, r.y)
                t_conv += (time()-_t)
                if abs(t[i]-r.t) > 1e-13:
                    msg = "INTEGRATION WARNING: time mismatch (diff at step {}: {:.3e})".format(i, abs(t[i]-r.t))
                    log.warning(msg)
                    raise Warning(msg)
                t[i] = r.t
                c.value = i
                i += 1

            if not r.successful():
                msg = "INTEGRATION WARNING: NOT successful!"
                log.warning(msg)
                raise Warning(msg)
        except Exception as e:
            trb = traceback.format_exc()
            return t[:i], x[:i], (e, trb)

    log.info("integration summary\n"+
             "integration     time {:.2g}s ({:.2%})\n".format(t_int, t_int / (t_int + t_conv))+
             "data conversion time {:.2g}s ({:.2%})\n".format(t_conv, t_conv / (t_int + t_conv)))

    return t, x, None
<|endoftext|>