### Navigation

- index
- modules |
- CCHR 1.0 documentation »
- Module code »
- src »

# Source code for src.offense_rules

    import cPickle
    from errors import *
    from itertools import izip

    class OffenseRules(object):
        def __init__(self, log):
            self.missing_codes = [9999, 999, 9, 9, 9, 99, 9]
            self.unknown_codes = [9999, 999, 9, 9, 9, 99, 9]
            self.not_coded = [-9999, -999, -9, -9, -9, -99, -9]
            self.default_pred_codes = [9999, 999, 9, 9, 9, 99, 9]
            self.vars = ['ncic', 'chg', 'inc', 'dom', 'weap', 'cdv', 'pg']
            self.log = log

            self.missing_map = zip(self.vars, self.missing_codes)
            self.missing_dict = dict([[var, missing] for var, missing in self.missing_map])
            self.unknown_map = zip(self.vars, self.unknown_codes)
            self.unknown_dict = dict([[var, unknown] for var, unknown in self.unknown_map])
            self.not_coded_map = zip(self.vars, self.unknown_codes)
            self.not_coded_dict = dict([[var, unknown] for var, unknown in self.unknown_map])

        def convert_inc(self, row, vars, ruleset, log_name):
            key = '|'.join(ruleset.metadata.get_key(row))
            if vars['inc'] is None:
                if key:
                    try:
                        if ruleset:
                            return ruleset.convert(key)
                        else:
                            #if no crosswalk defined than any value other than missing is logged
                            self.log.write(log_name, [row['id'], row['rapstatex'], key,
                                                      "New value for key (%s)" % '|'.join([k.name for k in ruleset.metadata.key_meta])])
                    except ConvertError:
                        self.log.write(log_name, [row['id'], row['rapstatex'], key,
                                                  "New value for key (%s)" % '|'.join([k.name for k in ruleset.metadata.key_meta])])
                        return self.unknown_dict['inc']
                else:
                    return self.missing_dict['inc']
            else:
                return vars['inc']

        def _convert_offenses(self, key, crosswalk, skip_coding = []):
            convert_key = '|'.join(key)
            missing_key = True
            temp_vars = {}

            for x in key:
                #if one of the values in the key is Not None than missing_key set to false and we break the loop
                if x:
                    missing_key = False
                    break

            if missing_key:
                #assign missing values when all variables in the key are None
                for k, v in self.missing_map:
                    if k not in skip_coding:
                        temp_vars[k] = v
                    else:
                        temp_vars[k] = None
            else:
                for k, v in izip(self.vars, crosswalk.convert(convert_key, split='|')):
                    temp_vars[k] = v

            return temp_vars

        def convert_offenses(self, row, rulesets, rule_order, _index=0, full_key=None, ground_truth={}):
            """
            @param rules: The crosswalk object containing all the RuleSets.
            @param rule_order: A list of tuples (x,y) where x = key to locate in RuleSet and y = name of RuleSet.
                          Length of list determines depth of recursion.
            @param skip_missing_coding: A list containing the names of offense variables to not code
                                        as missing if no match is found in crosswalk.
            """
            #TODO remove "recursion" because not really recursion
            vars = {}
            ruleset = rulesets[rule_order[_index]]

            if 'remove' in rule_order[_index]:
                #if a remove crosswalk is detected apply the delete_transform
                _key = ruleset.delete_transform(ruleset.metadata.get_key(row, as_str=True))
                _row = dict([(ruleset.metadata.key_meta[i].name, k) for i,k in enumerate(_key.split('|'))])
                #then use the transformed key in the next ruleset
                _index += 1
                ruleset = rulesets[rule_order[_index]]

                for key_meta in ruleset.metadata.key_meta:
                    #add any new key variables to the _row object
                    if key_meta.name not in _row:
                        _row[key_meta.name] = row[key_meta.name]

                key = ruleset.metadata.get_key(_row)
            else:
                key = ruleset.metadata.get_key(row)

            if not full_key:
                full_key = (ruleset.metadata.keys.keys(), ruleset.metadata.keys.values())
            else:
                for k, v in ruleset.metadata.keys.iteritems():
                    if k not in full_key[0]:
                        full_key[0].append(k)
                        full_key[1].append(v)

            index = _index + 1

            try:
                #code ancic, achg, ainc, adom, aweap, acdv, apg using key in ruleset
                vars = self._convert_offenses(key, ruleset, skip_coding = ruleset.skip_missing)

            except ConvertError:
                #check to see if we need to recurse
                if index == len(rule_order):
                    #output unknown values
                    for k, v in self.unknown_map:
                        vars[k] = None

                    #log no match using key and predictions
                    #TODO make full_key that contains all the key values for all the rulesets
                    self.log.write(self.log.var,
                                   [row['id'], row['rapstatex'],
                                    '|'.join([_k.name for _k in sorted(full_key[1], key= lambda k: k.order)]),
                                    '|'.join([_k.get_key(row) for _k in sorted(full_key[1], key= lambda k: k.order)]),
                                    "key not found in crosswalk_%s" % rule_order[_index][1]],
                                   type=2)
                else:
                    #dive down one layer
                     return self.convert_offenses(row, rulesets, rule_order, index, full_key, ground_truth)

            return vars

### Navigation

- index
- modules |
- CCHR 1.0 documentation »
- Module code »
- src »