def formula(commune, period, parameters):
        population_dgf = commune("population_dgf", period)
        revenu_par_habitant = commune("revenu_par_habitant", period)
        revenu_par_habitant_strate = commune("revenu_par_habitant_moyen",
                                             period)
        potentiel_financier_par_habitant = commune(
            "potentiel_financier_par_habitant", period)
        potentiel_financier_par_habitant_strate = commune(
            "potentiel_financier_par_habitant_moyen", period)
        dsr_eligible_fraction_bourg_centre = commune(
            "dsr_eligible_fraction_bourg_centre", period)
        dsr_eligible_fraction_perequation = commune(
            "dsr_eligible_fraction_perequation", period)

        limite_population = parameters(
            period).dotation_solidarite_rurale.seuil_nombre_habitants
        parametres_poids = parameters(
            period
        ).dotation_solidarite_rurale.cible.eligibilite.indice_synthetique
        poids_revenu = parametres_poids.poids_revenu
        poids_pot_fin = parametres_poids.poids_potentiel_financier

        return (
            (population_dgf < limite_population) *
            (dsr_eligible_fraction_bourg_centre
             | dsr_eligible_fraction_perequation) *
            (poids_pot_fin *
             safe_divide(potentiel_financier_par_habitant_strate,
                         potentiel_financier_par_habitant, 0) + poids_revenu *
             safe_divide(revenu_par_habitant_strate, revenu_par_habitant, 0)))
    def formula(commune, period, parameters):
        potentiel_financier = commune('potentiel_financier', period)
        outre_mer = commune('outre_mer', period)
        potentiel_financier_par_habitant = commune(
            'potentiel_financier_par_hectare', period)
        dsr_eligible_fraction_cible = commune("dsr_eligible_fraction_cible",
                                              period)
        population_dgf = commune('population_dgf', period)
        # oui le taille_max_commune est le même que pour le seuil d'éligibilité, notre paramétrisation est ainsi
        taille_max_commune = parameters(
            period).dotation_solidarite_rurale.seuil_nombre_habitants
        superficie = commune('superficie', period)
        communes_moins_10000 = (~outre_mer) * (population_dgf <
                                               taille_max_commune)

        pot_fin_par_hectare_10000 = safe_divide(
            np.sum(communes_moins_10000 * potentiel_financier),
            np.sum(communes_moins_10000 * superficie))

        facteur_pot_fin = max_(
            0,
            safe_divide((2 * pot_fin_par_hectare_10000 -
                         potentiel_financier_par_habitant),
                        pot_fin_par_hectare_10000, 0))

        return dsr_eligible_fraction_cible * population_dgf * facteur_pot_fin
    def formula(commune, period, parameters):
        potentiel_financier_par_habitant = commune(
            'potentiel_financier_par_habitant', period)
        potentiel_financier_par_habitant_strate = commune(
            'potentiel_financier_par_habitant_moyen', period)
        effort_fiscal = commune('effort_fiscal', period)
        dsr_eligible_fraction_cible = commune("dsr_eligible_fraction_cible",
                                              period)
        population_dgf = commune('population_dgf', period)

        plafond_effort_fiscal = parameters(
            period
        ).dotation_solidarite_rurale.attribution.plafond_effort_fiscal
        facteur_pot_fin = max_(
            0, 2 - safe_divide(potentiel_financier_par_habitant,
                               potentiel_financier_par_habitant_strate, 2))
        facteur_effort_fiscal = np.minimum(plafond_effort_fiscal,
                                           effort_fiscal)

        return dsr_eligible_fraction_cible * population_dgf * facteur_pot_fin * facteur_effort_fiscal
    def formula(commune, period, parameters):
        plancher_dgcl_population_dgf_majoree = 500
        plafond_dgcl_population_dgf_majoree = 200000
        facteur_du_coefficient_logarithmique = 1 / (log10(plafond_dgcl_population_dgf_majoree / plancher_dgcl_population_dgf_majoree))  # le fameux 0.38431089
        population_majoree_dgf = commune('population_dgf_majoree', period)
        population_majoree_dgf_an_dernier = commune('population_dgf_majoree', period.last_year)
        evolution_population = population_majoree_dgf - population_majoree_dgf_an_dernier

        facteur_minimum = parameters(period).dotation_forfaitaire.montant_minimum_par_habitant
        facteur_maximum = parameters(period).dotation_forfaitaire.montant_maximum_par_habitant
        dotation_supp_par_habitant = facteur_minimum + (facteur_maximum - facteur_minimum) * max_(0, min_(1, facteur_du_coefficient_logarithmique * log10(safe_divide(population_majoree_dgf, plancher_dgcl_population_dgf_majoree, 1))))
        return dotation_supp_par_habitant * evolution_population
    def formula_2019_01(commune, period, parameters):
        dsu_montant_total = commune('dsu_montant_total', period)
        dsu_an_precedent = commune('dsu_montant_total', period.last_year)
        montants_an_precedent = commune('dsu_montant_eligible', period.last_year)
        dsu_eligible = commune('dsu_eligible', period)
        total_a_distribuer = commune('dsu_montant_total_eligibles', period)
        rang_indice_synthetique_dsu_seuil_bas = commune('rang_indice_synthetique_dsu_seuil_bas', period)
        rang_indice_synthetique_dsu_seuil_haut = commune('rang_indice_synthetique_dsu_seuil_haut', period)

        nombre_elig_seuil_bas = commune('dsu_nombre_communes_eligibles_seuil_bas', period)
        nombre_elig_seuil_haut = commune('dsu_nombre_communes_eligibles_seuil_haut', period)
        effort_fiscal = commune('effort_fiscal', period)
        population_insee = commune('population_insee', period)
        population_qpv = commune('population_qpv', period)
        population_zfu = commune('population_zfu', period)
        population_dgf = commune('population_dgf', period)
        indice_synthetique_dsu = commune('indice_synthetique_dsu', period)

        facteur_classement_max = parameters(period).dotation_solidarite_urbaine.attribution.facteur_classement_max
        facteur_classement_min = parameters(period).dotation_solidarite_urbaine.attribution.facteur_classement_min
        poids_quartiers_prioritaires_ville = parameters(period).dotation_solidarite_urbaine.attribution.poids_quartiers_prioritaires_ville
        poids_zone_franche_urbaine = parameters(period).dotation_solidarite_urbaine.attribution.poids_zone_franche_urbaine
        plafond_effort_fiscal = parameters(period).dotation_solidarite_urbaine.attribution.plafond_effort_fiscal
        augmentation_max = parameters(period).dotation_solidarite_urbaine.attribution.augmentation_max
        seuil_bas = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_bas_nombre_habitants
        seuil_haut = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_haut_nombre_habitants

        pourcentage_augmentation_dsu = dsu_montant_total / dsu_an_precedent - 1

        eligible_groupe_haut = dsu_eligible * (seuil_haut <= population_dgf)
        eligible_groupe_bas = dsu_eligible * (seuil_bas <= population_dgf) * (seuil_haut > population_dgf)
        toujours_eligible_groupe_bas = eligible_groupe_bas * (montants_an_precedent > 0)
        toujours_eligible_groupe_haut = eligible_groupe_haut * (montants_an_precedent > 0)
        nouvellement_eligible_groupe_bas = eligible_groupe_bas * (montants_an_precedent == 0)
        nouvellement_eligible_groupe_haut = eligible_groupe_haut * (montants_an_precedent == 0)
        toujours_eligible = toujours_eligible_groupe_bas | toujours_eligible_groupe_haut
        # Détermination des scores
        facteur_classement_seuil_bas = np.where(rang_indice_synthetique_dsu_seuil_bas <= nombre_elig_seuil_bas, (facteur_classement_min - facteur_classement_max) * safe_divide((rang_indice_synthetique_dsu_seuil_bas - 1), (nombre_elig_seuil_bas - 1), 0) + facteur_classement_max, 0)
        facteur_classement_seuil_haut = np.where(rang_indice_synthetique_dsu_seuil_haut <= nombre_elig_seuil_haut, (facteur_classement_min - facteur_classement_max) * safe_divide((rang_indice_synthetique_dsu_seuil_haut - 1), (nombre_elig_seuil_haut - 1), 0) + facteur_classement_max, 0)
        facteur_classement = facteur_classement_seuil_bas + facteur_classement_seuil_haut
        facteur_effort_fiscal = min_(effort_fiscal, plafond_effort_fiscal)
        facteur_qpv = (1 + np.where(population_insee > 0, poids_quartiers_prioritaires_ville * population_qpv / population_insee, 0))
        facteur_zfu = (1 + np.where(population_insee > 0, poids_zone_franche_urbaine * population_zfu / population_insee, 0))
        score_attribution = indice_synthetique_dsu * population_dgf * facteur_classement * facteur_effort_fiscal * facteur_qpv * facteur_zfu
        score_anciens_eligibles_groupe_haut = (score_attribution * toujours_eligible_groupe_haut)
        score_nouveaux_eligibles_groupe_haut = (score_attribution * nouvellement_eligible_groupe_haut)
        score_anciens_eligibles_groupe_bas = (score_attribution * toujours_eligible_groupe_bas)
        score_nouveaux_eligibles_groupe_bas = (score_attribution * nouvellement_eligible_groupe_bas)
        # clef de répartition groupe haut/groupe bas
        total_pop_eligible_augmentation_groupe_bas = (toujours_eligible_groupe_bas * population_dgf).sum()
        total_pop_eligible_augmentation_groupe_haut = (toujours_eligible_groupe_haut * population_dgf).sum()
        total_pop_eligible_augmentation = total_pop_eligible_augmentation_groupe_haut + total_pop_eligible_augmentation_groupe_bas
        # s'il n'y a pas de population, on répartit selon la population totale des groupes (non spécifié par la loi)
        if not total_pop_eligible_augmentation:
            total_pop_eligible_augmentation_groupe_bas = (eligible_groupe_bas * population_dgf).sum()
            total_pop_eligible_augmentation_groupe_haut = (eligible_groupe_haut * population_dgf).sum()
            total_pop_eligible_augmentation = total_pop_eligible_augmentation_groupe_haut + total_pop_eligible_augmentation_groupe_bas

        part_augmentation_groupe_bas = total_pop_eligible_augmentation_groupe_bas / total_pop_eligible_augmentation
        part_augmentation_groupe_haut = 1 - part_augmentation_groupe_bas
        # clef de répartition : on attribue une valeur des points d'augmentation égale au pourcentage
        # d'augmentation de la DSU
        rapport_valeur_point = pourcentage_augmentation_dsu  # Le rapport valeur point dépend
        # probablement du groupe, mais on ignore les détails de son calcul
        total_points_groupe_bas = (score_anciens_eligibles_groupe_bas * rapport_valeur_point + score_nouveaux_eligibles_groupe_bas).sum()
        total_points_groupe_haut = (score_anciens_eligibles_groupe_haut * rapport_valeur_point + score_nouveaux_eligibles_groupe_haut).sum()
        # Détermination de la valeur du point
        montant_garanti_eligible = (toujours_eligible * montants_an_precedent).sum()
        valeur_point_groupe_bas = (total_a_distribuer - montant_garanti_eligible) * part_augmentation_groupe_bas / total_points_groupe_bas if total_points_groupe_bas else 0
        valeur_point_groupe_haut = (total_a_distribuer - montant_garanti_eligible) * part_augmentation_groupe_haut / total_points_groupe_haut if total_points_groupe_haut else 0
        montant_toujours_eligible_groupe_bas = (min_(valeur_point_groupe_bas * rapport_valeur_point * score_attribution, augmentation_max) + montants_an_precedent) * toujours_eligible_groupe_bas
        montant_toujours_eligible_groupe_haut = (min_(valeur_point_groupe_haut * rapport_valeur_point * score_attribution, augmentation_max) + montants_an_precedent) * toujours_eligible_groupe_haut
        montant_nouvellement_eligible_groupe_bas = valeur_point_groupe_bas * score_attribution * nouvellement_eligible_groupe_bas
        montant_nouvellement_eligible_groupe_haut = valeur_point_groupe_haut * score_attribution * nouvellement_eligible_groupe_haut
        return montant_toujours_eligible_groupe_bas + montant_toujours_eligible_groupe_haut + montant_nouvellement_eligible_groupe_bas + montant_nouvellement_eligible_groupe_haut
    def formula(commune, period, parameters):
        population_dgf = commune("population_dgf", period)
        outre_mer = commune('outre_mer', period)
        potentiel_financier = commune('potentiel_financier', period)
        potentiel_financier_par_habitant = commune('potentiel_financier_par_habitant', period)
        nombre_logements = commune('nombre_logements', period)
        nombre_logements_sociaux = commune('nombre_logements_sociaux', period)
        nombre_aides_au_logement = commune('nombre_beneficiaires_aides_au_logement', period)
        revenu = commune('revenu_total', period)
        population_insee = commune('population_insee', period)
        revenu_par_habitant = commune('revenu_par_habitant', period)

        seuil_bas = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_bas_nombre_habitants
        seuil_haut = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_haut_nombre_habitants
        ratio_max_pot_fin = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_rapport_potentiel_financier
        poids_pot_fin = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_potentiel_financier
        poids_logements_sociaux = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_logements_sociaux
        poids_aides_au_logement = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_aides_au_logement
        poids_revenu = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_revenu

        groupe_bas = (~outre_mer) * (seuil_bas <= population_dgf) * (seuil_haut > population_dgf)
        groupe_haut = (~outre_mer) * (seuil_haut <= population_dgf)

        pot_fin_bas = (np.sum(groupe_bas * potentiel_financier)
                / np.sum(groupe_bas * population_dgf)) if np.sum(groupe_bas * population_dgf) > 0 else 0
        pot_fin_haut = (np.sum(groupe_haut * potentiel_financier)
                / np.sum(groupe_haut * population_dgf)) if np.sum(groupe_haut * population_dgf) > 0 else 0

        # Retrait des communes au potentiel financier trop élevé, les communes restantes ont droit à un indice synthétique
        groupe_bas_score_positif = groupe_bas * (potentiel_financier_par_habitant < ratio_max_pot_fin * pot_fin_bas)
        groupe_haut_score_positif = groupe_haut * (potentiel_financier_par_habitant < ratio_max_pot_fin * pot_fin_haut)

        # Calcul des ratios moyens nécessaires au calcul de l'indice synthétique
        part_logements_sociaux_bas = (np.sum(groupe_bas * nombre_logements_sociaux)
                / np.sum(groupe_bas * nombre_logements)) if np.sum(groupe_bas * nombre_logements) > 0 else 0
        part_logements_sociaux_haut = (np.sum(groupe_haut * nombre_logements_sociaux)
                / np.sum(groupe_haut * nombre_logements)) if np.sum(groupe_haut * nombre_logements) > 0 else 0

        part_aides_logement_bas = (np.sum(groupe_bas * nombre_aides_au_logement)
                / np.sum(groupe_bas * nombre_logements)) if np.sum(groupe_bas * nombre_logements) > 0 else 0
        part_aides_logement_haut = (np.sum(groupe_haut * nombre_aides_au_logement)
                / np.sum(groupe_haut * nombre_logements)) if np.sum(groupe_haut * nombre_logements) > 0 else 0

        revenu_moyen_bas = (np.sum(groupe_bas * revenu)
                / np.sum(groupe_bas * population_insee)) if np.sum(groupe_bas * population_insee) > 0 else 0
        revenu_moyen_haut = (np.sum(groupe_haut * revenu)
                / np.sum(groupe_haut * population_insee)) if np.sum(groupe_haut * population_insee) > 0 else 0

        part_logements_sociaux_commune = safe_divide(nombre_logements_sociaux, nombre_logements)
        part_aides_logement_commune = safe_divide(nombre_aides_au_logement, nombre_logements)

        indice_synthetique_bas = groupe_bas_score_positif * (
            poids_pot_fin * safe_divide(pot_fin_bas, potentiel_financier_par_habitant)
            + poids_logements_sociaux * safe_divide(part_logements_sociaux_commune, part_logements_sociaux_bas)
            + poids_aides_au_logement * safe_divide(part_aides_logement_commune, part_aides_logement_bas)
            + poids_revenu * safe_divide(revenu_moyen_bas, revenu_par_habitant)
            )

        indice_synthetique_haut = groupe_haut_score_positif * (
            poids_pot_fin * safe_divide(pot_fin_haut, potentiel_financier_par_habitant)
            + poids_logements_sociaux * safe_divide(part_logements_sociaux_commune, part_logements_sociaux_haut)
            + poids_aides_au_logement * safe_divide(part_aides_logement_commune, part_aides_logement_haut)
            + poids_revenu * safe_divide(revenu_moyen_haut, revenu_par_habitant)
            )
        return indice_synthetique_bas + indice_synthetique_haut
示例#7
0
def test_safe_divide():
    a = np.array([1, 1, 0, 0, -1])
    b = np.array([1, 0, 2, 0, -1])
    assert all(safe_divide(a, b) == [1, 0, 0, 0, 1])
    assert all(safe_divide(a, b, 12) == [1, 12, 0, 12, 1])