* add SimulationRoundAnalyzer: count runs of simulation

* improve Render-structure
simu_flags
agp8x 2017-08-09 15:27:28 +02:00
parent 0711489a81
commit 06a606fbb8
9 changed files with 105 additions and 23 deletions

View File

@ -1,10 +1,10 @@
from .analyzer import Analyzer, Result from .analyzer import Analyzer, Result
from .analyzer.biogames import BoardDurationAnalyzer from .analyzer.biogames import BoardDurationAnalyzer, SimulationRoundsAnalyzer
from .analyzer.default import LogEntryCountAnalyzer, LocationAnalyzer, LogEntrySequenceAnalyzer, ActionSequenceAnalyzer from .analyzer.default import LogEntryCountAnalyzer, LocationAnalyzer, LogEntrySequenceAnalyzer, ActionSequenceAnalyzer
from .analyzer.locomotion import LocomotionActionAnalyzer, CacheSequenceAnalyzer from .analyzer.locomotion import LocomotionActionAnalyzer, CacheSequenceAnalyzer
from .analyzer.mask import MaskSpatials from .analyzer.mask import MaskSpatials
from .render import Render from .render import Render
from .render.default import PrintRender from .render.default import PrintRender, JSONRender
from .render.locomotion import LocomotionActionRelativeRender, LocomotionActionAbsoluteRender, \ from .render.locomotion import LocomotionActionRelativeRender, LocomotionActionAbsoluteRender, \
LocomotionActionRatioRender LocomotionActionRatioRender
@ -13,8 +13,13 @@ __MAPPING__ = {
LocomotionActionAnalyzer: [ LocomotionActionAnalyzer: [
LocomotionActionAbsoluteRender, LocomotionActionAbsoluteRender,
LocomotionActionRelativeRender, LocomotionActionRelativeRender,
LocomotionActionRatioRender], LocomotionActionRatioRender, ],
LogEntryCountAnalyzer: [
JSONRender,
],
SimulationRoundsAnalyzer: [
JSONRender,
]
} }

View File

@ -1,3 +1,5 @@
from collections import defaultdict
from . import Result, LogSettings, Analyzer from . import Result, LogSettings, Analyzer
@ -40,3 +42,21 @@ class BoardDurationAnalyzer(Analyzer):
super().__init__(settings) super().__init__(settings)
self.store = [] self.store = []
self.last = {} self.last = {}
class SimulationRoundsAnalyzer(Analyzer):
__name__ = "SimuRounds"
def __init__(self, settings: LogSettings):
super().__init__(settings)
self.store = defaultdict(lambda: 0)
def result(self) -> Result:
return Result(type(self), dict(self.store))
def process(self, entry: dict) -> bool:
entry_type = entry[self.settings.type_field]
if entry_type in self.settings.custom['simulation_rounds']:
if entry["answers"][self.settings.type_field] in self.settings.custom["simu_data"]:
self.store[entry['answers']["@id"]] += 1
return False

View File

@ -1,6 +1,17 @@
from typing import List from typing import List
from .. import Result from .. import Result
class Render: class Render:
result_types = []
def render(self, results: List[Result]): def render(self, results: List[Result]):
raise NotImplementedError() raise NotImplementedError()
def filter(self, results: List[Result]):
if len(self.result_types) == 0:
return results
return filter(self.__filter__, results)
def __filter__(self, obj: Result):
return obj.analysis() in self.result_types

View File

@ -1,8 +1,14 @@
import json
from typing import List from typing import List
from . import Render from . import Render, Result
class PrintRender(Render): class PrintRender(Render):
def render(self, results: List): def render(self, results: List[Result]):
print("\t" + "\n\t".join([str(r) for r in results])) print("\t" + "\n\t".join([str(r) for r in results]))
class JSONRender(Render):
def render(self, results: List[Result]):
print(json.dumps([r.get() for r in self.filter(results)], indent=1))

View File

@ -4,7 +4,7 @@ import matplotlib.pyplot as plt
import numpy as np import numpy as np
from . import Render from . import Render
from .. import Result from .. import Result, LocomotionActionAnalyzer
def plot(results: [[int]], ylabel: str, title: str, legend: (str,) = ("Locomotion", "Action")): def plot(results: [[int]], ylabel: str, title: str, legend: (str,) = ("Locomotion", "Action")):
@ -46,19 +46,23 @@ def filter_results(raw_results: [Result], keys) -> [[int]]:
return results return results
class LocomotionActionAbsoluteRender(Render): class LocomotionActionRender(Render):
result_types = [LocomotionActionAnalyzer]
class LocomotionActionAbsoluteRender(LocomotionActionRender):
def render(self, results: List[Result]): def render(self, results: List[Result]):
results = filter_results(results, ['locomotion_sum', 'action_sum']) results = filter_results(self.filter(results), ['locomotion_sum', 'action_sum'])
plot(results, "time", "abs loc/action") plot(results, "time", "abs loc/action")
class LocomotionActionRelativeRender(Render): class LocomotionActionRelativeRender(LocomotionActionRender):
def render(self, results: List[Result]): def render(self, results: List[Result]):
results = filter_results(results, ['locomotion_relative', 'action_relative']) results = filter_results(self.filter(results), ['locomotion_relative', 'action_relative'])
plot(results, "fraction of time", "rel loc/action") plot(results, "fraction of time", "rel loc/action")
class LocomotionActionRatioRender(Render): class LocomotionActionRatioRender(LocomotionActionRender):
def render(self, results: List[Result]): def render(self, results: List[Result]):
results = filter_results(results, ['locomotion_action_ratio']) results = filter_results(self.filter(results), ['locomotion_action_ratio'])
plot_line(results, ylabel="Ratio", title="Locomotion/Action Ratio") plot_line(results, ylabel="Ratio", title="Locomotion/Action Ratio")

View File

@ -10,6 +10,7 @@ class LogSettings:
analyzers = [] analyzers = []
boards = None boards = None
sequences = None sequences = None
custom = None
def __init__(self, json_dict): def __init__(self, json_dict):
self.log_format = json_dict['logFormat'] self.log_format = json_dict['logFormat']
@ -22,6 +23,8 @@ class LogSettings:
print(mod, name) print(mod, name)
self.analyzers.append(getattr(sys.modules[mod], name)) self.analyzers.append(getattr(sys.modules[mod], name))
self.sequences = json_dict['sequences'] self.sequences = json_dict['sequences']
if 'custom' in json_dict:
self.custom = json_dict['custom']
def __repr__(self): def __repr__(self):
return str({ return str({
@ -32,6 +35,7 @@ class LogSettings:
"analyzers": self.analyzers, "analyzers": self.analyzers,
"boards": self.boards, "boards": self.boards,
"sequences": self.sequences, "sequences": self.sequences,
"custom": self.custom,
}) })

View File

@ -1,5 +1,5 @@
{ {
"logFormat": "sqlite", "logFormat": "zip",
"entryType": "@class", "entryType": "@class",
"spatials": [ "spatials": [
"de.findevielfalt.games.game2.instance.log.entry.LogEntryLocation" "de.findevielfalt.games.game2.instance.log.entry.LogEntryLocation"
@ -19,7 +19,8 @@
"ActionSequenceAnalyzer", "ActionSequenceAnalyzer",
"BoardDurationAnalyzer", "BoardDurationAnalyzer",
"LocomotionActionAnalyzer", "LocomotionActionAnalyzer",
"CacheSequenceAnalyzer" "CacheSequenceAnalyzer",
"SimulationRoundsAnalyzer"
] ]
}, },
"sequences": { "sequences": {
@ -28,5 +29,9 @@
"@class": "de.findevielfalt.games.game2.instance.log.entry.LogEntryInstanceAction", "@class": "de.findevielfalt.games.game2.instance.log.entry.LogEntryInstanceAction",
"action.@class": "de.findevielfalt.games.game2.instance.action.CacheEnableAction" "action.@class": "de.findevielfalt.games.game2.instance.action.CacheEnableAction"
} }
},
"custom":{
"simulation_rounds": ["de.findevielfalt.games.game2.instance.log.entry.LogEntryQuestion"],
"simu_data": ["de.findevielfalt.games.game2.instance.data.sequence.simulation.SimulationBoardData"]
} }
} }

13
load.py
View File

@ -1,6 +1,7 @@
import json import json
import sqlite3 import sqlite3
import tempfile
import zipfile
from json import loads as json_loads from json import loads as json_loads
@ -36,7 +37,15 @@ class SQLiteLoader(Loader):
yield json_loads(json) yield json_loads(json)
class ZipSQLiteLoader(SQLiteLoader):
def load(self, file: str):
with zipfile.ZipFile(file, "r") as zipped_log, tempfile.TemporaryDirectory() as tmp:
zipped_log.extract("instance_log.sqlite", path=tmp)
super(ZipSQLiteLoader, self).load("{dir}/instance_log.sqlite".format(dir=tmp))
LOADERS = { LOADERS = {
"json": JSONLoader, "json": JSONLoader,
"sqlite": SQLiteLoader "sqlite": SQLiteLoader,
"zip": ZipSQLiteLoader
} }

View File

@ -6,7 +6,7 @@ import analyzers
def process_log(log_id: str, settings: LogSettings) -> List[Analyzer]: def process_log(log_id: str, settings: LogSettings) -> List[Analyzer]:
logfile = "data/inst_{id}/instance_log.sqlite".format(id=log_id) logfile = "data/inst_{id}.{format}".format(id=log_id, format=settings.log_format)
loader = LOADERS[settings.log_format]() loader = LOADERS[settings.log_format]()
try: try:
loader.load(logfile) loader.load(logfile)
@ -24,17 +24,35 @@ def process_log(log_id: str, settings: LogSettings) -> List[Analyzer]:
if __name__ == '__main__': if __name__ == '__main__':
settings = load_settings("biogames2.json") settings = load_settings("biogames2.json")
log_ids = ["56d9b64144ab44e7b90bf766f3be32e3", "85a9ad58951e4fbda26f860c9b66f567"] log_ids = [
"20d4244719404ffab0ca386c76e4b112",
"56d9b64144ab44e7b90bf766f3be32e3",
"dc2cdc28ca074715b905e4aa5badff10",
"e32b16998440475b994ab46d481d3e0c", ]
log_ids = [
"34fecf49dbaca3401d745fb467",
"44ea194de594cd8d63ac0314be",
"57c444470dbf88605433ca935c",
"78e0c545b594e82edfad55bd7f",
"91abfd4b31a5562b1c66be37d9",
"597b704fe9ace475316c345903",
"e01a684aa29dff9ddd9705edf8",
"fbf9d64ae0bdad0de7efa3eec6",
"fe1331481f85560681f86827ec",
"fec57041458e6cef98652df625", ]
results = [] results = []
for log_id in log_ids: for log_id in log_ids:
for analysis in process_log(log_id, settings): for analysis in process_log(log_id, settings):
print("* Result for " + analysis.name()) print("* Result for " + analysis.name())
# print(analysis.result()) # print(analysis.result())
# print(analysis.render()) # print(analysis.render())
if analysis.name() in ("LocomotionAction"): results.append(analysis.result())
results.append(analysis.result()) if False:
for r in get_renderer(analyzers.LocomotionActionAnalyzer): for r in get_renderer(analyzers.LocomotionActionAnalyzer):
r().render(results) r().render(results)
jr = analyzers.JSONRender()
jr.result_types = [analyzers.SimulationRoundsAnalyzer]
jr.render(results)
# for analyzers in analyzers: # for analyzers in analyzers:
# if analyzers.name() in ["LogEntryCount", "ActionSequenceAnalyzer"]: # if analyzers.name() in ["LogEntryCount", "ActionSequenceAnalyzer"]: