diff --git a/docs/entity.md b/docs/entity.md index ce3784726299767a174201b06538adf8c36c5f6d..8a035d8a246cc52991e5e85082f770dcf47578ef 100644 --- a/docs/entity.md +++ b/docs/entity.md @@ -63,14 +63,14 @@ As described in `robofish.io`, Files and Entities have useful properties. <small> -| Entity function | Description | -| ------------------------------------------------ | ------------------------------------------------------------------------ | -| `robofish.io.entity.Entity.positions` | Positions as a `(timesteps, 2 (x, y))` array. | -| `robofish.io.entity.Entity.orientations` | Orientations as a `(timesteps, 2 (ori_x, ori_y))` array. | -| `robofish.io.entity.Entity.orientations_rad` | Orientations as a `(timesteps, 1 (ori_rad))` array. | -| `robofish.io.entity.Entity.poses` | Poses as a `(timesteps, 4 (x, y, x_ori, y_ori))` array. | -| `robofish.io.entity.Entity.poses_rad` | Poses as a `(timesteps, 3(x, y, ori_rad))` array. | -| `robofish.io.entity.Entity.actions_speeds_turns` | Speed and turn as a `(timesteps - 1, 2 (speed_cm/s, turn_rad/s))` array. | +| Entity function | Description | +| ------------------------------------------------ | -------------------------------------------------------------------------------------- | +| `robofish.io.entity.Entity.positions` | Positions as a `(timesteps, 2 (x, y))` array. | +| `robofish.io.entity.Entity.orientations` | Orientations as a `(timesteps, 2 (ori_x, ori_y))` array. | +| `robofish.io.entity.Entity.orientations_rad` | Orientations as a `(timesteps, 1 (ori_rad))` array. | +| `robofish.io.entity.Entity.poses` | Poses as a `(timesteps, 4 (x, y, x_ori, y_ori))` array. | +| `robofish.io.entity.Entity.poses_rad` | Poses as a `(timesteps, 3(x, y, ori_rad))` array. | +| `robofish.io.entity.Entity.actions_speeds_turns` | Speed and turn as a `(timesteps - 1, 2 (speed in cm/frame, turn in rad/frame))` array. | </small> diff --git a/docs/index.md b/docs/index.md index b4a967dfa2166ef96ce5a3e8625598599c9bcd68..a6bcde60c0b5b8300c5af79cf9acb052593db52c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -124,14 +124,14 @@ In the same scheme the following properties are available: <small> -| File/ Entity function | Description | -| ----------------------------- | ------------------------------------------------------------------------------------ | -| *entity_*positions | Positions as a `(*entities*, timesteps, 2 (x, y))` arary. | -| *entity_*orientations | Orientations as a `(*entities*, timesteps, 2 (ori_x, ori_y))` arary. | -| *entity_*orientations_rad | Orientations as a `(*entities*, timesteps, 1 (ori_rad))` arary. | -| *entity_*poses | Poses as a `(*entities*, timesteps, 4 (x, y, x_ori, y_ori))` array. | -| *entity_*poses_rad | Poses as a `(*entities*, timesteps, 3(x, y, ori_rad))` array. | -| *entity_*actions_speeds_turns | Speed and turn as a `(*entities*, timesteps - 1, 2 (speed_cm/s, turn_rad/s))` array. | +| File/ Entity function | Description | +| ----------------------------- | -------------------------------------------------------------------------------------------------- | +| *entity_*positions | Positions as a `(*entities*, timesteps, 2 (x, y))` array. | +| *entity_*orientations | Orientations as a `(*entities*, timesteps, 2 (ori_x, ori_y))` array. | +| *entity_*orientations_rad | Orientations as a `(*entities*, timesteps, 1 (ori_rad))` array. | +| *entity_*poses | Poses as a `(*entities*, timesteps, 4 (x, y, x_ori, y_ori))` array. | +| *entity_*poses_rad | Poses as a `(*entities*, timesteps, 3(x, y, ori_rad))` array. | +| *entity_*actions_speeds_turns | Speed and turn as a `(*entities*, timesteps - 1, 2 (speed in cm/frame, turn in rad/frame))` array. | </small> diff --git a/pyproject.toml b/pyproject.toml index a762f8d2475cb105f012e121bc2369b9ee3141be..c3be3e375a9942b25d1cf504dde45d005a6f4eb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ extend-ignore = "E203" [tool.black] line-length = 88 -include ='' +include ='\.py' [tool.pytest.ini_options] filterwarnings = ["error"] \ No newline at end of file diff --git a/src/robofish/evaluate/evaluate.py b/src/robofish/evaluate/evaluate.py index 48f889b4e05e92787569e271c54f22f01d068dce..d62c6ce49fd11273037e32358f89d2a69f18b4cb 100644 --- a/src/robofish/evaluate/evaluate.py +++ b/src/robofish/evaluate/evaluate.py @@ -73,11 +73,18 @@ def evaluate_speed( """ files_per_path = [robofish.io.read_multiple_files(p) for p in paths] speeds = [] + frequency = None + for k, files in enumerate(files_per_path): path_speeds = [] for p, file in files.items(): + assert frequency is None or frequency == file.frequency + frequency = file.frequency + for e_speeds_turns in file.entity_actions_speeds_turns: - path_speeds = np.concatenate([path_speeds, e_speeds_turns[:, 0]]) + path_speeds = np.concatenate( + [path_speeds, e_speeds_turns[:, 0] * frequency] + ) speeds.append(path_speeds) if labels is None: @@ -91,7 +98,7 @@ def evaluate_speed( plt.title("Agent speeds") plt.xlabel("Speed [cm/s]") plt.ylabel("Frequency") - plt.ticklabel_format(useOffset=False) + plt.ticklabel_format(useOffset=False, style="plain") plt.legend() plt.tight_layout() @@ -130,14 +137,14 @@ def evaluate_turn( frequency = file.frequency for e_speeds_turns in file.entity_actions_speeds_turns: - path_turns.extend(e_speeds_turns[:, 1]) + path_turns.extend(np.rad2deg(e_speeds_turns[:, 1])) turns.append(path_turns) if labels is None: labels = paths - left_quantile = np.min(np.quantile(np.array(turns), 0.001, axis=1)) - right_quantile = np.max(np.quantile(np.array(turns), 0.999, axis=1)) + left_quantile = np.min(np.quantile(np.array(turns), 0.005, axis=1)) + right_quantile = np.max(np.quantile(np.array(turns), 0.995, axis=1)) plt.hist( turns, bins=41, @@ -148,7 +155,7 @@ def evaluate_turn( plt.title("Agent turns") plt.xlabel("Change in orientation [Degree / timestep at %dhz]" % frequency) plt.ylabel("Frequency") - plt.ticklabel_format(useOffset=False) + plt.ticklabel_format(useOffset=False, style="plain") plt.legend() # plt.tight_layout() diff --git a/src/robofish/io/entity.py b/src/robofish/io/entity.py index f1b836aa93b0d144cdb3615f915b23fffc26d14d..21d157d16733b537788fb2d2e22fdd026b0370ae 100644 --- a/src/robofish/io/entity.py +++ b/src/robofish/io/entity.py @@ -241,15 +241,12 @@ class Entity(h5py.Group): def actions_speeds_turns(self): """Calculate the speed, turn and from the recorded positions and orientations. - The turn is calculated by the change of orientation. + The turn is calculated by the change of orientation between frames. The speed is calculated by the distance between the points, projected on the new orientation vector. The sideway change of position cannot be represented with this method. Returns: - An array with shape (number_of_positions -1, 3). - The first column is the speed (distance projected on new orientation). - The second column is the turning angle. - + An array with shape (number_of_positions -1, 2 (speed in cm/frame, turn in rad/frame). """ ori = self.orientations diff --git a/src/robofish/io/file.py b/src/robofish/io/file.py index ff211af4aaa4133ae6fb6868b939db4dd5d6ec96..822f0152671b04f97111a5877d353a80c71e1c64 100644 --- a/src/robofish/io/file.py +++ b/src/robofish/io/file.py @@ -463,6 +463,15 @@ class File(h5py.File): @property def entity_actions_speeds_turns(self): + """Calculate the speed, turn and from the recorded positions and orientations. + + The turn is calculated by the change of orientation between frames. + The speed is calculated by the distance between the points, projected on the new orientation vector. + The sideway change of position cannot be represented with this method. + + Returns: + An array with shape (number_of_entities, number_of_positions -1, 2 (speed in cm/frame, turn in rad/frame). + """ return self.select_entity_property( None, entity_property=Entity.actions_speeds_turns )