The Higher Education and Research forge

Home My Page Projects Code Snippets Project Openings EMULSION public releases
Summary Activity Surveys SCM Listes Sympa

SCM Repository

1 """
3 """
4 from   pathlib               import Path
5 import csv
6 import dateutil.parser       as     dup
7 import numpy                 as     np
8 from emulsion.agent.managers import MetapopProcessManager
10 DATA_FILE = 'moves.csv'
12 #===============================================================
13 # CLASS Metapopulation (LEVEL 'metapop')
14 #===============================================================
15 class Metapopulation(MetapopProcessManager):
16     """
17     level of the metapop.
19     """
20     def initialize_level(self, **others):
21         """Initialize an instance of Metapopulation.
22         Additional initialization parameters can be introduced here if needed.
23         """
24         # read a CSV data file for moves:
25         # date of movement, source herd, destination herd, age group, quantity
27         # and restructure it according to origin_date and delta_t:
28         # {step: {source_id: [(dest_id, age_group, qty), ...],
29         #         ...},
30         #  ...}
31         origin = self.model.origin_date
32         step_duration = self.model.step_duration
33         moves = {}
34         with open(Path(self.model.input_dir, DATA_FILE)) as csvfile:
35             # read the CSV file
36             csvreader = csv.DictReader(csvfile, delimiter=',')
37             for row in csvreader:
38                 day = dup.parse(row['date'])
39                 if day < origin:
40                     # ignore dates before origin_date
41                     continue
42                 # convert dates into simulation steps
43                 step = (day - origin) // step_duration
44                 # group information by step and source herd
45                 if step not in moves:
46                     moves[step] = {}
47                 src, dest, qty = int(row['source']), int(row['dest']), int(row['qty'])
48                 if src not in moves[step]:
49                     moves[step][src] = []
50                 moves[step][src].append([dest, row['age'], qty])
51         self.moves = moves
53     #----------------------------------------------------------------
54     # Processes
55     #----------------------------------------------------------------
56     def exchange_animals(self):
57         """
59         => INDICATE HERE HOW TO PERFORM PROCESS exchange_animals.
60         """
61         if self.statevars.step in self.moves:
62             herds = self.get_populations()
63             for source in self.moves[self.statevars.step]:
64                 for dest, age, qty in self.moves[self.statevars.step][source]:
65                     # neither source/dest in simulated herds
66                     if (source not in herds) and (dest not in herds):
67                         # print('ignoring movement from {} to {} (outside the metapopulation)'.format(source, dest))
68                         continue
69                     # source not in simulated herds: create animal from prototype
70                     if source not in herds:
71                         # print('movement to {} coming from outside the metapopulation'.format(dest))
73                         # retrieve prototype definition from the model
74                         prototype = self.model.get_prototype(name='imported_movement', level='animals')
75                         # change age group to comply with movement
76                         prototype['age_group'] = self.get_model_value(age)
77                         animals = [herds[dest].new_atom(custom_prototype=prototype)
78                                    for _ in range(qty)]
79                         # print('importing', animals)
80                     else:
81                         # find convenient animals
82                         candidates = herds[source].select_atoms('age_group', age, process='aging')
83                         # try to move the appropriate quantity
84                         nb = min(len(candidates), qty)
85                         animals = np.random.choice(candidates, nb, replace=False)
86                         herds[source].remove_atoms(animals)
87                         # print('removing', animals, 'from', source)
88                         # update variable 'sold' in source herd
89                         herds[source].statevars.sold += len(animals)
90                     if dest not in herds:
91                         pass
92                         # print('movement from {} going outside the metapopulation'.format(source))
93                     else:
94                         herds[dest].add_atoms(animals)
95                         # update variable 'purchased' in dest herd
96                         herds[dest].statevars.purchased += len(animals)
97                         # print('adding', animals, 'to', dest)