rfr = individu.foyer_fiscal('rfr', period.n_2)
L'appel ci-dessus est à peu près équivalent à
simulation = individu.simulation
rfr = simulation.calculate('rfr', period.n_2)
rfr = simulation.populations['foyer_fiscal'].project(rfr)
L'opération de projection est à la base assez simple…
Prenons par exemple un vecteur de 5 individus, les variables invididuelles étant disons age=[10,30,5,8,45]; il se répartit en deux foyers fiscaux, la population des foyers fiscaux est un vecteur avec par exemple rfr=[40000,60000]. Un vecteur "pivot" affecte chaque individu à un foyer fiscal: members_entity_id=[0,0,0,1,1].
Dans ce cas projeter revient à prendre rfr[members_entity_id] => [40000,40000,40000,60000,60000] soit "pour chaque individu le RFR du foyer fiscal auquel il appartient".
Dans les coulisses c'est plus compliqué, il y a de la magie pour éviter de manipuler explicitement l'instance de Simulation.
individu
est de type Population
Sa création se fait dans TaxBenefitSystem::instantiate_entities
L'instance appartient à Simulation: une Simulation, une instance de Population ou GroupPopulation pour chaque instance de Entity
individu.foyer_fiscal
déclenche Population::__getattr__
La valeur renvoyée est de type EntityToPersonProjector (appelons-la projector
), nouvellement instanciée en lui fournissant un paramètre de type Population obtenu par lookup dans la Simulation (simulation.populations['foyer_fiscal']
), la population dite "de référence", appelons-la reference
individu.foyer_fiscal(*args)
se résoud donc en projector(*args)
Ce dernier appel déclenche Projector::__call__
Celui-ci va à son tour invoquer Population::call via reference(*args)
; puis postérieurement, appeler Projector::transform sur le vecteur résultat, qui pour l'essentiel effectue un appel à Population::project
Population:__call__
quant à lui est un wrapper pour Simulation::calculate()