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

de8a96e8f2c2512e4d18ef96fb1d0c09789c4b24
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,
37                                        fieldnames=['date','source','dest', 'age', 'qty'],
38                                        delimiter=',')
39             for row in csvreader:
40                 day = dup.parse(row['date'])
41                 if day < origin:
42                     # ignore dates before origin_date
43                     continue
44                 # convert dates into simulation steps
45                 step = (day - origin) // step_duration
46                 # group information by step and source herd
47                 if step not in moves:
48                     moves[step] = {}
49                     src, dest, qty = int(row['source']), int(row['dest']), int(row['qty'])
50                     if src not in moves[step]:
51                         moves[step][src] = []
52                         moves[step][src].append([dest, row['age'], qty])
53         self.moves = moves
55     #----------------------------------------------------------------
56     # Processes
57     #----------------------------------------------------------------
58     def exchange_animals(self):
59         """
61         => INDICATE HERE HOW TO PERFORM PROCESS exchange_animals.
62         """
63         if self.statevars.step in self.moves:
64             herds = self.get_populations()
65             for source in self.moves[self.statevars.step]:
66                 for dest, age, qty in self.moves[self.statevars.step][source]:
67                     # neither source/dest in simulated herds
68                     if (source not in herds) and (dest not in herds):
69                         # print('ignoring movement from {} to {} (outside the metapopulation)'.format(source, dest))
70                         continue
71                     # source not in simulated herds: create animal from prototype
72                     if source not in herds:
73                         # print('movement to {} coming from outside the metapopulation'.format(dest))
75                         # retrieve prototype definition from the model
76                         prototype = self.model.get_prototype(name='imported_movement', level='animals')
77                         # change age group to comply with movement
78                         prototype['age_group'] = self.get_model_value(age)
79                         animals = [herds[dest].new_atom(custom_prototype=prototype)
80                                    for _ in range(qty)]
81                         # print('importing', animals)
82                     else:
83                         # find convenient animals
84                         candidates = herds[source].select_atoms('age_group', age, process='aging')
85                         # try to move the appropriate quantity
86                         nb = min(len(candidates), qty)
87                         animals = np.random.choice(candidates, nb, replace=False)
88                         herds[source].remove_atoms(animals)
89                         # print('removing', animals, 'from', source)
90                         # update variable 'sold' in source herd
91                         herds[source].statevars.sold += len(animals)
92                     if dest not in herds:
93                         pass
94                         # print('movement from {} going outside the metapopulation'.format(source))
95                     else:
96                         herds[dest].add_atoms(animals)
97                         # update variable 'purchased' in dest herd
98                         herds[dest].statevars.purchased += len(animals)
99                         # print('adding', animals, 'to', dest)