# Path: seal/lib/mr/hadoop_event_monitor.py
# class HadoopEventMonitor(EventMonitor):
#     """
#     Event monitor implementation to log information through the
#     Hadoop context.
#     """
#     def __init__(self, event_class, logger, ctx):
#         """
#         Parameters:
#         event_class:  the category in which all counters will be created.
#         logger:  logger object to use
#         ctx:  Hadoop context
#         """
#         self.event_class = event_class
#         self.logger = logger
#         self.ctx = ctx
#         self.__start_times = {}
#         self.__counters = {}
# 
#     def __get_counter(self, name, timing=False):
#         if not self.__counters.has_key(name):
#             if timing:
#                 self.add_counter(name, "TIME_" + name.upper() + " (ms)")
#             else:
#                 self.add_counter(name, name.upper())
#         return self.__counters[name]
# 
#     def __get_timing_counter(self, name):
#         return self.__get_counter(name, timing=True)
# 
#     def start(self, s):
#         self.__start_times[s] = time.time()
# 
#     def stop(self, s, write_status=True):
#         delta = time.time() - self.__start_times[s]
#         self.ctx.incrementCounter(self.__get_timing_counter(s), int(delta/TIME_TICK))
#         if write_status:
#             status = "done with %s (%.3f s)" % (s, delta)
#             self.ctx.setStatus(status)
#             self.log_info(status)
# 
#     def stop_batch(self, s, offset, n):
#         delta = time.time() - self.__start_times[s]
#         self.ctx.incrementCounter(self.__get_timing_counter(s), int(delta/TIME_TICK))
#         status = "done with %s (offset=%d, n=%d) (%.3f s)" % (s, offset, n, delta)
#         self.ctx.setStatus(status)
#         self.log_info(status)
# 
#     def count(self, name, value=1):
#         self.ctx.incrementCounter(self.__get_counter(name), value)
# 
#     def has_counter(self, name):
#         return self.__counters.has_key(name)
# 
#     def add_counter(self, name, display_name=None):
#         if self.__counters.has_key(name):
#             raise ValueError("counter '%s' is already defined" % name)
#         self.__counters[name] = self.ctx.getCounter(self.event_class, display_name if display_name else name.upper())
# 
#     #################################
#     # logging methods
#     #################################
#     def new_status(self, status_msg):
#         self.ctx.setStatus(status_msg)
#         self.log_debug(status_msg)
# 
#     def log_debug(self, *args):
#         self.logger.debug(*args)
# 
#     def log_info(self, *args):
#         self.logger.info(*args)
# 
#     def log_warning(self, *args):
#         self.logger.warning(*args)
# 
#     def log_error(self, *args):
#         self.logger.error(*args)
# 
#     def log_critical(self, *args):
#         self.logger.critical(*args)
# 
# Path: seal/lib/mr/emit_sam_link.py
# class EmitSamLink(HitProcessorChainLink):
#     def __init__(self, context, event_monitor, next_link = None):
#         super(EmitSamLink, self).__init__(next_link)
#         self.ctx = context
#         self.output_formatter = SamFormatter(strip_pe_tag=True)
#         self.event_monitor = event_monitor
# 
#     def process(self, original, pair):
#         for hit in pair:
#             if hit:
#                 k, v = self.output_formatter.format(hit).split("\t", 1)
#                 self.ctx.emit(str(k), str(v))
#                 self.event_monitor.count("emitted sam records", 1)
# 
#         super(EmitSamLink, self).process(original, pair) # forward pair to next element in chain


import logging
import seal.lib.io.protobuf_mapping as protobuf_mapping
import seal.lib.deprecation_utils as deprecation_utils
import seal.seqal as seqal
from pydoop.pipes import Reducer
from pydoop.utils import jc_configure, jc_configure_bool
from seal.lib.mr.hadoop_event_monitor import HadoopEventMonitor
from seal.lib.mr.emit_sam_link import EmitSamLink
        jc = ctx.getJobConf()
        logger = logging.getLogger("seqal")
        jobconf = deprecation_utils.convert_job_conf(jc, self.DeprecationMap, logger)

        jc_configure(self, jobconf, 'seal.seqal.log.level', 'log_level', 'INFO')
        jc_configure_bool(self, jobconf, 'seal.seqal.discard_duplicates', 'discard_duplicates', False)

        logging.basicConfig(level=self.log_level)

        self.event_monitor = HadoopEventMonitor(self.COUNTER_CLASS, logging.getLogger("reducer"), ctx)
        self.__output_sink = EmitSamLink(ctx, self.event_monitor)

    def __process_unmapped_pairs(self, ctx):
        while ctx.nextValue():
            value = ctx.getInputValue()
            pair = protobuf_mapping.unserialize_pair(value)
            self.__output_sink.process(pair)

    def reduce(self, ctx):
        # create the "workspace"
        self.__pairs = []
        self.__unpaired = []

        # gather input
        key_values = ctx.getInputKey().split(':')

        if key_values[0] == seqal.UNMAPPED_STRING:
            # pair of unmapped sequences
            self.__process_unmapped_pairs(ctx)
        else:

# Path: seal/lib/mr/hadoop_event_monitor.py
# class HadoopEventMonitor(EventMonitor):
#     """
#     Event monitor implementation to log information through the
#     Hadoop context.
#     """
#     def __init__(self, event_class, logger, ctx):
#         """
#         Parameters:
#         event_class:  the category in which all counters will be created.
#         logger:  logger object to use
#         ctx:  Hadoop context
#         """
#         self.event_class = event_class
#         self.logger = logger
#         self.ctx = ctx
#         self.__start_times = {}
#         self.__counters = {}
# 
#     def __get_counter(self, name, timing=False):
#         if not self.__counters.has_key(name):
#             if timing:
#                 self.add_counter(name, "TIME_" + name.upper() + " (ms)")
#             else:
#                 self.add_counter(name, name.upper())
#         return self.__counters[name]
# 
#     def __get_timing_counter(self, name):
#         return self.__get_counter(name, timing=True)
# 
#     def start(self, s):
#         self.__start_times[s] = time.time()
# 
#     def stop(self, s, write_status=True):
#         delta = time.time() - self.__start_times[s]
#         self.ctx.incrementCounter(self.__get_timing_counter(s), int(delta/TIME_TICK))
#         if write_status:
#             status = "done with %s (%.3f s)" % (s, delta)
#             self.ctx.setStatus(status)
#             self.log_info(status)
# 
#     def stop_batch(self, s, offset, n):
#         delta = time.time() - self.__start_times[s]
#         self.ctx.incrementCounter(self.__get_timing_counter(s), int(delta/TIME_TICK))
#         status = "done with %s (offset=%d, n=%d) (%.3f s)" % (s, offset, n, delta)
#         self.ctx.setStatus(status)
#         self.log_info(status)
# 
#     def count(self, name, value=1):
#         self.ctx.incrementCounter(self.__get_counter(name), value)
# 
#     def has_counter(self, name):
#         return self.__counters.has_key(name)
# 
#     def add_counter(self, name, display_name=None):
#         if self.__counters.has_key(name):
#             raise ValueError("counter '%s' is already defined" % name)
#         self.__counters[name] = self.ctx.getCounter(self.event_class, display_name if display_name else name.upper())
# 
#     #################################
#     # logging methods
#     #################################
#     def new_status(self, status_msg):
#         self.ctx.setStatus(status_msg)
#         self.log_debug(status_msg)
# 
#     def log_debug(self, *args):
#         self.logger.debug(*args)
# 
#     def log_info(self, *args):
#         self.logger.info(*args)
# 
#     def log_warning(self, *args):
#         self.logger.warning(*args)
# 
#     def log_error(self, *args):
#         self.logger.error(*args)
# 
#     def log_critical(self, *args):
#         self.logger.critical(*args)
# 
# Path: seal/lib/mr/emit_sam_link.py
# class EmitSamLink(HitProcessorChainLink):
#     def __init__(self, context, event_monitor, next_link = None):
#         super(EmitSamLink, self).__init__(next_link)
#         self.ctx = context
#         self.output_formatter = SamFormatter(strip_pe_tag=True)
#         self.event_monitor = event_monitor
# 
#     def process(self, original, pair):
#         for hit in pair:
#             if hit:
#                 k, v = self.output_formatter.format(hit).split("\t", 1)
#                 self.ctx.emit(str(k), str(v))
#                 self.event_monitor.count("emitted sam records", 1)
# 
#         super(EmitSamLink, self).process(original, pair) # forward pair to next element in chain


# Path: seal/seqal/reducer.py
import logging
import seal.lib.io.protobuf_mapping as protobuf_mapping
import seal.lib.deprecation_utils as deprecation_utils
import seal.seqal as seqal
from pydoop.pipes import Reducer
from pydoop.utils import jc_configure, jc_configure_bool
from seal.lib.mr.hadoop_event_monitor import HadoopEventMonitor
from seal.lib.mr.emit_sam_link import EmitSamLink

        jc = ctx.getJobConf()
        logger = logging.getLogger("seqal")
        jobconf = deprecation_utils.convert_job_conf(jc, self.DeprecationMap, logger)

        jc_configure(self, jobconf, 'seal.seqal.log.level', 'log_level', 'INFO')
        jc_configure_bool(self, jobconf, 'seal.seqal.discard_duplicates', 'discard_duplicates', False)

        logging.basicConfig(level=self.log_level)

        self.event_monitor = HadoopEventMonitor(self.COUNTER_CLASS, logging.getLogger("reducer"), ctx)
        self.__output_sink = EmitSamLink(ctx, self.event_monitor)

    def __process_unmapped_pairs(self, ctx):
        while ctx.nextValue():
            value = ctx.getInputValue()
            pair = protobuf_mapping.unserialize_pair(value)
            self.__output_sink.process(pair)

    def reduce(self, ctx):
        # create the "workspace"
        self.__pairs = []
        self.__unpaired = []

        # gather input
        key_values = ctx.getInputKey().split(':')

        if key_values[0] == seqal.UNMAPPED_STRING:
            # pair of unmapped sequences
            self.__process_unmapped_pairs(ctx)
        else:

            if len(key_values) != 3: