def date_diff(warn_date, gsr_date):
     """
     Computes date difference based on warning date and event date.
     :param warn_date: Event_Date in the warning
     :param gsr_date: Event_Date in the GSR
     :return: integer, negative values mean the warning was later than the event
     """
     gsr_d = parse(gsr_date).date()
     warn_d = parse(warn_date).date()
     date_diff = (gsr_d - warn_d).days
     return date_diff
    def score_one(warn_,
                  event_,
                  max_dist=Defaults.MAX_DIST,
                  dist_buffer=Defaults.DIST_BUFFER,
                  max_date_diff=Defaults.MAX_DATE_DIFF,
                  legit_actors=ACTORS,
                  wildcards=WILDCARD_ACTORS,
                  ls_weight=Defaults.LS_WEIGHT,
                  ds_weight=Defaults.DS_WEIGHT,
                  as_weight=Defaults.AS_WEIGHT,
                  ess_weight=Defaults.ESS_WEIGHT):
        """
        Scores a single warning against a single event
        :param warn_: Dict with data for a warning
        :param event_: Dict with data for an event
        :return: Dict with scoring details
        """
        bad_qs = False
        error_list = []
        notice_list = []
        if ls_weight < 0:
            bad_qs = True
            error_list.append("LS Weight must be positive")
        if ds_weight < 0:
            bad_qs = True
            error_list.append("DS Weight must be positive")
        if as_weight < 0:
            bad_qs = True
            error_list.append("AS Weight must be positive")
        if ess_weight < 0:
            bad_qs = True
            error_list.append("ESS Weight must be positive")
        weight_sum = ls_weight + ds_weight + as_weight + ess_weight
        if weight_sum != 4.0:
            notice_list.append("Reweighting so that sum of weights is 4.0")
            ls_weight = 4 * ls_weight / weight_sum
            ds_weight = 4 * ds_weight / weight_sum
            as_weight = 4 * as_weight / weight_sum
            ess_weight = 4 * ess_weight / weight_sum

        out_dict = dict()
        # Compute the distance
        out_dict[JSONField.WARNING_ID] = warn_[JSONField.WARNING_ID]
        out_dict[JSONField.EVENT_ID] = event_[JSONField.EVENT_ID]
        if error_list:
            out_dict["Errors"] = error_list
        else:
            warn_lat = warn_[JSONField.LATITUDE]
            warn_long = warn_[JSONField.LONGITUDE]
            event_lat = event_[JSONField.LATITUDE]
            event_long = event_[JSONField.LONGITUDE]
            loc_approx = event_[JSONField.APPROXIMATE_LOCATION]
            out_dict[JSONField.APPROXIMATE_LOCATION] = loc_approx
            dist = distance((warn_lat, warn_long), (event_lat, event_long)).km
            out_dict["Distance"] = dist
            warn_event_date = warn_[JSONField.EVENT_DATE]
            event_event_date = event_[JSONField.EVENT_DATE]
            gsr_d = parse(event_event_date).date()
            warn_d = parse(warn_event_date).date()
            date_diff = (gsr_d - warn_d).days
            date_diff = np.abs(date_diff)
            out_dict["Date Difference"] = date_diff
            ls = MaScorer.location_score(dist, loc_approx, max_dist,
                                         dist_buffer)
            out_dict[ScoreComponents.LS] = ls
            date_delta = Scorer.date_diff(warn_event_date, event_event_date)
            ds = Scorer.date_score(date_delta, max_date_diff)
            out_dict[ScoreComponents.DS] = ds
            # Event Subtype
            warn_es = warn_[JSONField.SUBTYPE]
            gsr_es = event_[JSONField.SUBTYPE]
            ess = MaScorer.event_subtype_score(warn_es, gsr_es)
            out_dict[ScoreComponents.ESS] = ess
            # Actor Score
            warn_actor = warn_[JSONField.ACTOR]
            event_actor = event_[JSONField.ACTOR]
            _as = MaScorer.actor_score(warn_actor, event_actor, legit_actors,
                                       wildcards)
            out_dict[ScoreComponents.AS] = _as
            if min(ls, ds) == 0:
                qs = 0
            else:
                qs = ls_weight * ls + ds_weight * ds + as_weight * _as + ess_weight * ess
            out_dict[ScoreComponents.QS] = qs
        # Quality Score
        if notice_list:
            out_dict["Notices"] = notice_list
        return out_dict