# Path: python/pipeline/exceptions.py
# class PipelineException(Exception):
#     """Base pipeline exception. Prints the message plus any specific info."""
#     def __init__(self, message, info=None):
#         info_message = '\nError info: ' + repr(info) if info else ''
#         super().__init__(message + info_message)
#         self.info = info


import os
import h5py
import itertools
import numpy as np
import datajoint as dj
        import bisect
        import matplotlib.pyplot as plt
from commons import lab
from scipy import ndimage
from pipeline.utils import h5
from datajoint.hash import key_hash
from .exceptions import PipelineException
from pipeline import meso, stack, mice, experiment, shared
        from scipy.spatial import distance
        from mpl_toolkits.mplot3d import Axes3D
    """

    def convert_valves(num):
        """ Converts decimal number encoding valve states into boolean array
        :param num: int. Decimal number encoding valve state in binary
        :returns: numpy array of booleans. Array encodes valve state (True=OPEN) starting with the smallest valve number
            ex. decimal(10) -> [False, True, False, True] -> 2nd and 4th valve open.
        """

        # Format integer into binary, then convert each 0/1 into boolean
        # Finally, reverse list to make first index encode first valve
        valve_states = [bool(int(d)) for d in format(int(num), 'b')][::-1]
        return np.array(valve_states)

    def make(self, key):

        print(f'Populating trials for {key}')

        # Get olfactory h5 path and filename
        olfactory_path = (OdorSession & key).fetch1('odor_path')
        local_path = lab.Paths().get_local_path(olfactory_path)
        filename_base = (OdorRecording & key).fetch1('filename')
        digital_filename = os.path.join(local_path, filename_base + '_D_%d.h5')

        # Load olfactory data
        digital_data = h5.read_digital_olfaction_file(digital_filename)

        # Check valve data ends with all valves closed
        if digital_data['valves'][-1] != 0:
            msg = f'Error: Final valve state is open! Ending time cannot be calculated for {key}.'

# Path: python/pipeline/exceptions.py
# class PipelineException(Exception):
#     """Base pipeline exception. Prints the message plus any specific info."""
#     def __init__(self, message, info=None):
#         info_message = '\nError info: ' + repr(info) if info else ''
#         super().__init__(message + info_message)
#         self.info = info


# Path: python/pipeline/odor.py
import os
import h5py
import itertools
import numpy as np
import datajoint as dj
        import bisect
        import matplotlib.pyplot as plt
from commons import lab
from scipy import ndimage
from pipeline.utils import h5
from datajoint.hash import key_hash
from .exceptions import PipelineException
from pipeline import meso, stack, mice, experiment, shared
        from scipy.spatial import distance
        from mpl_toolkits.mplot3d import Axes3D

    """

    def convert_valves(num):
        """ Converts decimal number encoding valve states into boolean array
        :param num: int. Decimal number encoding valve state in binary
        :returns: numpy array of booleans. Array encodes valve state (True=OPEN) starting with the smallest valve number
            ex. decimal(10) -> [False, True, False, True] -> 2nd and 4th valve open.
        """

        # Format integer into binary, then convert each 0/1 into boolean
        # Finally, reverse list to make first index encode first valve
        valve_states = [bool(int(d)) for d in format(int(num), 'b')][::-1]
        return np.array(valve_states)

    def make(self, key):

        print(f'Populating trials for {key}')

        # Get olfactory h5 path and filename
        olfactory_path = (OdorSession & key).fetch1('odor_path')
        local_path = lab.Paths().get_local_path(olfactory_path)
        filename_base = (OdorRecording & key).fetch1('filename')
        digital_filename = os.path.join(local_path, filename_base + '_D_%d.h5')

        # Load olfactory data
        digital_data = h5.read_digital_olfaction_file(digital_filename)

        # Check valve data ends with all valves closed
        if digital_data['valves'][-1] != 0:
            msg = f'Error: Final valve state is open! Ending time cannot be calculated for {key}.'

            raise PipelineException(msg)