(self, config_path)
| 52 | |
| 53 | class SkeletonBuilder: |
| 54 | def __init__(self, config_path): |
| 55 | self.config_path = config_path |
| 56 | self.cfg = read_config(config_path) |
| 57 | # Find uncropped labeled data |
| 58 | self.df = None |
| 59 | found = False |
| 60 | root = os.path.join(self.cfg["project_path"], "labeled-data") |
| 61 | for dir_ in os.listdir(root): |
| 62 | folder = os.path.join(root, dir_) |
| 63 | if os.path.isdir(folder) and not any(folder.endswith(s) for s in ("cropped", "labeled")): |
| 64 | self.df = pd.read_hdf(os.path.join(folder, f"CollectedData_{self.cfg['scorer']}.h5")) |
| 65 | self.df = drop_likelihood_columns(self.df) |
| 66 | row, col = self.pick_labeled_frame() |
| 67 | if "individuals" in self.df.columns.names: |
| 68 | self.df = self.df.xs(col, axis=1, level="individuals") |
| 69 | self.xy = self.df.loc[row].values.reshape((-1, 2)) |
| 70 | missing = np.flatnonzero(np.isnan(self.xy).all(axis=1)) |
| 71 | if not missing.size: |
| 72 | found = True |
| 73 | break |
| 74 | if self.df is None: |
| 75 | raise OSError("No labeled data were found.") |
| 76 | |
| 77 | self.bpts = self.df.columns.get_level_values("bodyparts").unique() |
| 78 | if not found: |
| 79 | warnings.warn( |
| 80 | f"A fully labeled animal could not be found. " |
| 81 | f"{', '.join(self.bpts[missing])} will need to be manually connected in the config.yaml.", |
| 82 | stacklevel=2, |
| 83 | ) |
| 84 | self.tree = KDTree(self.xy) |
| 85 | # Handle image previously annotated on a different platform |
| 86 | if isinstance(row, str): |
| 87 | sep = "/" if "/" in row else "\\" |
| 88 | row = row.split(sep) |
| 89 | self.image = io.imread(os.path.join(self.cfg["project_path"], *row)) |
| 90 | self.inds = set() |
| 91 | self.segs = set() |
| 92 | # Draw the skeleton if already existent |
| 93 | if self.cfg["skeleton"]: |
| 94 | for bone in self.cfg["skeleton"]: |
| 95 | pair = np.flatnonzero(self.bpts.isin(bone)) |
| 96 | if len(pair) != 2: |
| 97 | continue |
| 98 | pair_sorted = tuple(sorted(pair)) |
| 99 | self.inds.add(pair_sorted) |
| 100 | self.segs.add(tuple(map(tuple, self.xy[pair_sorted, :]))) |
| 101 | self.lines = LineCollection(self.segs, colors=mcolors.to_rgba(self.cfg["skeleton_color"])) |
| 102 | self.lines.set_picker(True) |
| 103 | self.build_ui() |
| 104 | self.display() |
| 105 | |
| 106 | def build_ui(self): |
| 107 | self.fig = plt.figure() |
nothing calls this directly
no test coverage detected