diff --git a/Stuff/Modules/cm.py b/Stuff/Modules/cm.py index 7d3fd0b..9fa1144 100644 --- a/Stuff/Modules/cm.py +++ b/Stuff/Modules/cm.py @@ -626,7 +626,7 @@ def getPeriodicity(self, time = 20, startTime = 0, minSpeed = 10, skip = 12, smo for minT in minTime: t0 = startTime * 60000 - x0, y0 = self.data[start][7:9] + x0, y0 = self.data[start][self.indices] minT *= 1000 speeds = deque() @@ -635,7 +635,7 @@ def getPeriodicity(self, time = 20, startTime = 0, minSpeed = 10, skip = 12, smo for content in self.data[start+skip::skip]: if content[1] > time: break - x1, y1 = content[7:9] + x1, y1 = content[self.indices] t1 = content[1] speeds.append((sqrt(((x1 - x0)**2 + (y1 - y0)**2)) / self.trackerResolution) / ((t1 - t0) / 1000)) @@ -731,10 +731,10 @@ def getSpeedAfterShock(self, time = 20, startTime = 0, after = 25, absolute = Fa angles = [] cx, cy = self.centerX, self.centerY for shock in selected: - x1, y1 = self.data[shock][7:9] + x1, y1 = self.data[shock][self.indices] if len(self.data) <= shock + after: break - x2, y2 = self.data[shock + after][7:9] + x2, y2 = self.data[shock + after][self.indices] angle = ((degrees(atan2(x2 - cx, y2 - cy + 0.0000001)) - degrees(atan2(x1 - cx, y1 - cy + 0.0000001)) + 180) % 360) - 180 angles.append(angle) diff --git a/Stuff/Modules/cmsf.py b/Stuff/Modules/cmsf.py new file mode 100644 index 0000000..0b26023 --- /dev/null +++ b/Stuff/Modules/cmsf.py @@ -0,0 +1,77 @@ +""" +Copyright 2013 Štěpán Bahník + +This file is part of Carousel Maze Manager. + +Carousel Maze Manager is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Carousel Maze Manager is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Carousel Maze Manager. If not, see . +""" + +from cm import CM +from singleframe import SF + + +class CMSF(SF, CM): + def __init__(self, nameA, *_): + + self.nameA = nameA + self.data = [] + self.interpolated = set() + self.indices = slice(2,4) + + # in cache? + if self.nameA in CMSF.cache: + self.__dict__ = CMSF.cache[self.nameA] + return + + # processing data from arena frame + with open(self.nameA, "r") as infile: + self.width = 60 + self.centerAngle = 0 + self._processHeader(infile) + self._processRoomFile(infile) + + # discards missing points from beginning of self.data + self._correctMissingFromBeginning() + + # exception used for example when all lines are wrong (all positions are 0, 0) + if not self.data: + raise Exception("Failure in data initialization.") + + # caching + CMSF.cache[self.nameA] = self.__dict__ + if len(CMSF.cache) > 15: + CMSF.cache.popitem(last = False) + + + def _removalCondition(self, row, i, before, reflection): + """conditions in order of appearance: + large speed between the row and before row + same position as in the reflection row + we should expect the position to be closer to before row than to the + reflection row - determined by speed + wrong points in the row + """ + return any((self._computeSpeed(self.data[row + i], before) > 250, + self.data[row + i][2:4] == self.data[row][2:4], + self._computeSpeed(reflection, self.data[row + i]) * 30 < + self._computeSpeed(before, self.data[row + i]), + row + i in self.interpolated)) + + + def _cacheRemoval(self): + if self.nameA in CMSF.cache: + CMSF.cache.pop(self.nameA) + + def removeReflections(self, *args, bothframes = False, **kwargs): + super().removeReflections(*args, bothframes = bothframes, **kwargs) diff --git a/Stuff/Modules/graphs.py b/Stuff/Modules/graphs.py index 1fc9a14..d28de65 100644 --- a/Stuff/Modules/graphs.py +++ b/Stuff/Modules/graphs.py @@ -375,6 +375,7 @@ def compute(self, cm, smooth = 10): cm.data[start:] if line[1] <= self.maxTime] self.maxY = self.radius + 10 + self.points = dists def CM_loaded(self, cm, initTime = 0, minTime = 0, maxTime = "max"): diff --git a/Stuff/Modules/menu.py b/Stuff/Modules/menu.py index 0236342..05d2974 100644 --- a/Stuff/Modules/menu.py +++ b/Stuff/Modules/menu.py @@ -73,12 +73,9 @@ def __init__(self, root): self.menu_options.add_command(label = "General options", command = self.generalOptions) self.menu_options.add_separator() self.menu_options.add_command(label = "Reset all options", command = self.resetOptions) - self.menu_task.add_radiobutton(label = "Carousel Maze", variable = self.task, value = "CM", - command = self.changedTask) - self.menu_task.add_radiobutton(label = "Morris Watter Maze", variable = self.task, - value = "MWM", command = self.changedTask) - self.menu_task.add_radiobutton(label = "Open Field", variable = self.task, value = "OF", - command = self.changedTask) + for task, name in m.fullname.items(): + self.menu_task.add_radiobutton(label = name, variable = self.task, value = task, + command = self.changedTask) self.menu_help.add_command(label = "About", command = self.about) self.menu_help.add_command(label = "Citation", command = self.citation) self.menu_help.add_separator() diff --git a/Stuff/Modules/mode.py b/Stuff/Modules/mode.py index 260ab37..b8a94be 100644 --- a/Stuff/Modules/mode.py +++ b/Stuff/Modules/mode.py @@ -17,13 +17,14 @@ along with Carousel Maze Manager. If not, see . """ -from collections import namedtuple +from collections import namedtuple, OrderedDict from cm import CM from mwm import MWM from of import OF -from parameters import ParametersCM, ParametersMWM, ParametersOF +from cmsf import CMSF +from parameters import ParametersCM, ParametersMWM, ParametersOF, ParametersCMSF mode = None @@ -40,15 +41,20 @@ dispatch = {"CM": Task(CM, "pair", ParametersCM()), "MWM": Task(MWM, "one", ParametersMWM()), - "OF": Task(OF, "one", ParametersOF())} + "OF": Task(OF, "one", ParametersOF()), + "CMSF": Task(CMSF, "one", ParametersCMSF())} + +fullname = OrderedDict() +fullname["CM"] = "Carousel maze" +fullname["CMSF"] = "Carousel maze (single frame)" +fullname["MWM"] = "Morris watter maze" +fullname["OF"] = "Open field" -fullname = {"CM": "Carousel maze", - "MWM": "Morris watter maze", - "OF": "Open field"} time = {"CM": 20, "MWM": 1, - "OF": 10} + "OF": 10, + "CMSF": 20} def changeMode(newMode): diff --git a/Stuff/Modules/parameters.py b/Stuff/Modules/parameters.py index 3defe79..48f2fdd 100644 --- a/Stuff/Modules/parameters.py +++ b/Stuff/Modules/parameters.py @@ -197,6 +197,14 @@ def __init__(self): +class ParametersCMSF(OrderedDict): + def __init__(self): + super().__init__() + for name, parameter in ParametersCM().items(): + if name not in ("Room frame filename",): + self[name] = parameter + + diff --git a/Stuff/Modules/tools.py b/Stuff/Modules/tools.py index 6c169ec..76f49fd 100644 --- a/Stuff/Modules/tools.py +++ b/Stuff/Modules/tools.py @@ -164,8 +164,14 @@ def okFun(self): def addFun(self): "adds selected time to the text widget as well as to the selected batch time" - start = int(self.timeFrame.startTimeVar.get()) - end = int(self.timeFrame.timeVar.get()) + try: + start = int(self.timeFrame.startTimeVar.get()) + except ValueError: + start = float(self.timeFrame.startTimeVar.get()) + try: + end = int(self.timeFrame.timeVar.get()) + except ValueError: + end = float(self.timeFrame.timeVar.get()) newTime = (start, end) self.batchTime.append(newTime) self._updateText() diff --git a/Stuff/Modules/version.py b/Stuff/Modules/version.py index e26de1a..d0b13bc 100644 --- a/Stuff/Modules/version.py +++ b/Stuff/Modules/version.py @@ -21,8 +21,8 @@ def version(): return ['0', '4', '0'] def date(): - return "23 September 2013" + return "9 February 2014" def copyleft(): - return "2013" + return "2013-2014"