1 | from evolalg_steps.base.step import Step |
---|
2 | import os |
---|
3 | from framsfiles import writer as framswriter |
---|
4 | |
---|
5 | |
---|
6 | class PopulationSave(Step): |
---|
7 | def __init__(self, path, fields, provider=None, *args, **kwargs): |
---|
8 | super(PopulationSave, self).__init__(*args, **kwargs) |
---|
9 | self.path = path |
---|
10 | self.provider = provider |
---|
11 | self.fields = fields |
---|
12 | |
---|
13 | @staticmethod |
---|
14 | def ensure_dir(path): |
---|
15 | directory = os.path.dirname(path) |
---|
16 | if directory == "": |
---|
17 | return |
---|
18 | if not os.path.exists(directory): |
---|
19 | os.makedirs(directory) |
---|
20 | |
---|
21 | def call(self, population): |
---|
22 | super(PopulationSave, self).call(population) |
---|
23 | PopulationSave.ensure_dir(self.path) |
---|
24 | provider = self.provider |
---|
25 | if provider is None: |
---|
26 | provider = population |
---|
27 | |
---|
28 | #TODO instead of "fitness", write all fields used as fitness source with their original names (e.g. "velocity", "vertpos" etc.). In evaluation, set all attributes we get from Framsticks so that here we get all original names and values. Or, even better, introduce a dict field in Individual and assign to it everything that we get from Framsticks on evaluation (and add a filtering ability, i.e. when None - save all, when a list of field names - save only the enumerated fields) |
---|
29 | with open(self.path, "w") as outfile: |
---|
30 | for ind in provider: |
---|
31 | keyval = {} |
---|
32 | for k in self.fields: # construct a dictionary with criteria names and their values |
---|
33 | keyval[k] = getattr(ind, self.fields[k]) |
---|
34 | outfile.write(framswriter.from_collection({"_classname": "org", **keyval})) |
---|
35 | outfile.write("\n") |
---|
36 | |
---|
37 | print("Saved '%s' (%d)" % (self.path, len(provider))) |
---|
38 | return population |
---|