# Path: lib/exception.py
# class MissingException(Exception):
# 
#     def __init__(self, message):
#         # Call the base class constructor with the parameters it needs
#         super(MissingException, self).__init__(message)
#         self.returncode = 4
# 
#         logg = Logger('MissingException')
#         logg.error(message)
# 
# Path: lib/sitkaAPI.py
# def latestMetricInstance(metricInstanceList):
#     """
#     get the single latest metric instance
#     :param metricInstanceList:
#     :return:
#     """
#     result = latestMetricInstances(metricInstanceList, True)
#     if result is not None and len(result) > 0:
#         return result[0]
#     else:
#         return None
# 
# Path: lib/exception.py
# class DataException(Exception):
# 
#     def __init__(self, message):
#         # Call the base class constructor with the parameters it needs
#         super(DataException, self).__init__(message)
#         self.returncode = 2
#         logg = Logger('DataException')
#         logg.error(message)
# 
# class MissingException(Exception):
# 
#     def __init__(self, message):
#         # Call the base class constructor with the parameters it needs
#         super(MissingException, self).__init__(message)
#         self.returncode = 4
# 
#         logg = Logger('MissingException')
#         logg.error(message)
# 
# Path: lib/metrics.py
# class CHaMPMetric(object):
# 
#     # This is the dictionary representation of the object
#     # in its null state.
#     TEMPLATE = {}
# 
#     def __init__(self, *args, **kwargs):
#         # First initialize our logger and our empty metrics
#         self.log = Logger(self.__module__)
#         self.metrics = deepcopy(self.TEMPLATE)
# 
#         # Now try a calculation
#         try:
#             self.calc(*args, **kwargs)
#         except (DataException, MissingException), e:
#             self.log.warning("Could not complete metric calculation")
#             self.metrics = deepcopy(self.TEMPLATE)
# 
#     def calc(self, *args, **kwargs):
#         """
#         Needs to be overloaded in the children
#         :return:
#         """
#         raise Exception("YOU MUST IMPLEMENT THIS")


from lib.exception import MissingException
from lib.sitkaAPI import latestMetricInstance
from lib.exception import DataException, MissingException
from lib.metrics import CHaMPMetric
        self.metrics = self._calc(undercutVals, metricInstance)

    @staticmethod
    def _calc(undercutVals, visitTopoVals):
        """
        Calculate undercut metrics
        :param undercutVals: dictionary of undercut API data
        :param visitTopoVals: dictionary of visit topo metrics
        :return: metrics dictionary
        """

        # initialize all metrics as zero
        dMetrics = {
            'Length' : 0.0,
            'LengthPercent' : 0.0,
            'Area' :  0.0,
            'AreaPerecent' : 0.0
        }

        if len(undercutVals) > 0:
            # Calculate the total undercut length and area
            for undercut in undercutVals:
                dMetrics['Length'] += undercut['EstimatedLength']
                try:
                    dMetrics['Area'] += undercut['EstimatedLength'] * (undercut['Width25Percent'] + undercut['Width50Percent'] + undercut['Width75Percent']) / 3.0
                except TypeError, e:
                    raise DataException("Undercut: Unhandled 'None' values during length calculation")

            # Calculate the percent length and area of the site that is undercut
            if visitTopoVals['Lgth_Wet'] is None:

# Path: lib/exception.py
# class MissingException(Exception):
# 
#     def __init__(self, message):
#         # Call the base class constructor with the parameters it needs
#         super(MissingException, self).__init__(message)
#         self.returncode = 4
# 
#         logg = Logger('MissingException')
#         logg.error(message)
# 
# Path: lib/sitkaAPI.py
# def latestMetricInstance(metricInstanceList):
#     """
#     get the single latest metric instance
#     :param metricInstanceList:
#     :return:
#     """
#     result = latestMetricInstances(metricInstanceList, True)
#     if result is not None and len(result) > 0:
#         return result[0]
#     else:
#         return None
# 
# Path: lib/exception.py
# class DataException(Exception):
# 
#     def __init__(self, message):
#         # Call the base class constructor with the parameters it needs
#         super(DataException, self).__init__(message)
#         self.returncode = 2
#         logg = Logger('DataException')
#         logg.error(message)
# 
# class MissingException(Exception):
# 
#     def __init__(self, message):
#         # Call the base class constructor with the parameters it needs
#         super(MissingException, self).__init__(message)
#         self.returncode = 4
# 
#         logg = Logger('MissingException')
#         logg.error(message)
# 
# Path: lib/metrics.py
# class CHaMPMetric(object):
# 
#     # This is the dictionary representation of the object
#     # in its null state.
#     TEMPLATE = {}
# 
#     def __init__(self, *args, **kwargs):
#         # First initialize our logger and our empty metrics
#         self.log = Logger(self.__module__)
#         self.metrics = deepcopy(self.TEMPLATE)
# 
#         # Now try a calculation
#         try:
#             self.calc(*args, **kwargs)
#         except (DataException, MissingException), e:
#             self.log.warning("Could not complete metric calculation")
#             self.metrics = deepcopy(self.TEMPLATE)
# 
#     def calc(self, *args, **kwargs):
#         """
#         Needs to be overloaded in the children
#         :return:
#         """
#         raise Exception("YOU MUST IMPLEMENT THIS")


# Path: tools/topoauxmetrics/methods/undercut.py
from lib.exception import MissingException
from lib.sitkaAPI import latestMetricInstance
from lib.exception import DataException, MissingException
from lib.metrics import CHaMPMetric

        self.metrics = self._calc(undercutVals, metricInstance)

    @staticmethod
    def _calc(undercutVals, visitTopoVals):
        """
        Calculate undercut metrics
        :param undercutVals: dictionary of undercut API data
        :param visitTopoVals: dictionary of visit topo metrics
        :return: metrics dictionary
        """

        # initialize all metrics as zero
        dMetrics = {
            'Length' : 0.0,
            'LengthPercent' : 0.0,
            'Area' :  0.0,
            'AreaPerecent' : 0.0
        }

        if len(undercutVals) > 0:
            # Calculate the total undercut length and area
            for undercut in undercutVals:
                dMetrics['Length'] += undercut['EstimatedLength']
                try:
                    dMetrics['Area'] += undercut['EstimatedLength'] * (undercut['Width25Percent'] + undercut['Width50Percent'] + undercut['Width75Percent']) / 3.0
                except TypeError, e:
                    raise DataException("Undercut: Unhandled 'None' values during length calculation")

            # Calculate the percent length and area of the site that is undercut
            if visitTopoVals['Lgth_Wet'] is None:

                raise DataException("Lgth_Wet cannot be null")