Maps DLC project bodyparts to the corresponding SuperAnimal bodyparts. The conversion table must satisfy the following conditions (checked by validate): - All SuperAnimal bodyparts must be valid (defined for the SuperAnimal model) - All project bodyparts must be valid (defined f
| 19 | |
| 20 | @dataclass |
| 21 | class ConversionTable: |
| 22 | """Maps DLC project bodyparts to the corresponding SuperAnimal bodyparts. |
| 23 | |
| 24 | The conversion table must satisfy the following conditions (checked by validate): |
| 25 | - All SuperAnimal bodyparts must be valid (defined for the SuperAnimal model) |
| 26 | - All project bodyparts must be valid (defined for the DLC project) |
| 27 | """ |
| 28 | |
| 29 | super_animal: str |
| 30 | project_bodyparts: list[str] |
| 31 | super_animal_bodyparts: list[str] |
| 32 | table: dict[str, str] |
| 33 | |
| 34 | def __post_init__(self): |
| 35 | """Validates the table.""" |
| 36 | self.validate() |
| 37 | |
| 38 | def to_array(self) -> np.ndarray: |
| 39 | """ |
| 40 | Returns: |
| 41 | An array mapping the indices of SuperAnimal bodyparts |
| 42 | |
| 43 | Raises: |
| 44 | ValueError: If the conversion table is misconfigured. |
| 45 | """ |
| 46 | self.validate() |
| 47 | sa_indices = {sa_bpt: i for i, sa_bpt in enumerate(self.super_animal_bodyparts)} |
| 48 | sa_bpt_ordering = [self.table[bpt] for bpt in self.converted_bodyparts()] |
| 49 | return np.array([sa_indices[sa_bpt] for sa_bpt in sa_bpt_ordering]) |
| 50 | |
| 51 | def converted_bodyparts(self) -> list[str]: |
| 52 | """Returns: The project bodyparts included in this ordered""" |
| 53 | return [bpt for bpt in self.project_bodyparts if bpt in self.table] |
| 54 | |
| 55 | def validate(self) -> None: |
| 56 | """ |
| 57 | Raises: |
| 58 | ValueError: If the conversion table is misconfigured. |
| 59 | """ |
| 60 | project_bpts = set(self.project_bodyparts) |
| 61 | sa_bpts = set(self.super_animal_bodyparts) |
| 62 | |
| 63 | mapped_sa = set(self.table.values()) |
| 64 | mapped_project = set(self.table.keys()) |
| 65 | |
| 66 | # check all mapped SuperAnimal bodyparts are in the config |
| 67 | if len(mapped_sa.difference(sa_bpts)) != 0: |
| 68 | extra_bodyparts = set(mapped_sa).difference(sa_bpts) |
| 69 | raise ValueError( |
| 70 | f"Some bodyparts in your mapping are not in the {self.super_animal} " |
| 71 | f"model: {extra_bodyparts}. Available bodyparts are {' '.join(sa_bpts)}" |
| 72 | ) |
| 73 | |
| 74 | # check all given bodyparts are in the project configuration |
| 75 | if len(mapped_project.difference(project_bpts)) != 0: |
| 76 | extra_bodyparts = mapped_project.difference(project_bpts) |
| 77 | raise ValueError( |
| 78 | "Some bodyparts in your mapping are not in your project configuration: " |
no outgoing calls
no test coverage detected