Skip to content

dataset

Dataclasses for storing datasets.

Dataset dataclass

Container class for photogrammetry and laser tracker dataset. Provides a dict like interface for accessing points by their labels.

Attributes:

Name Type Description
data_dict dict[str, NDArray[float64]]

Dict of data points. You should genrally not touch this directly.

Source code in lat_alignment/dataset.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
@dataclass
class Dataset:
    """
    Container class for photogrammetry and laser tracker dataset.
    Provides a dict like interface for accessing points by their labels.

    Attributes
    ----------
    data_dict : dict[str, NDArray[np.float64]]
        Dict of data points.
        You should genrally not touch this directly.
    """

    data_dict: dict[str, NDArray[np.float64]]

    def _clear_cache(self):
        self.__dict__.pop("points", None)
        self.__dict__.pop("labels", None)
        self.__dict__.pop("target", None)
        self.__dict__.pop("target_labels", None)

    def __setattr__(self, name, value):
        if name == "data_dict":
            self._clear_cache()
        return super().__setattr__(name, value)

    def __setitem__(self, key, item):
        self._clear_cache()
        self.data_dict[key] = item

    def __getitem__(self, key):
        return self.data_dict[key]

    def __repr__(self):
        return repr(self.data_dict)

    def __len__(self):
        return len(self.data_dict)

    def __delitem__(self, key):
        self._clear_cache()
        del self.data_dict[key]

    def __contains__(self, item):
        return item in self.data_dict

    def __iter__(self):
        return iter(self.data_dict)

    @cached_property
    def points(self) -> NDArray[np.float64]:
        """
        Get all points in the dataset as an array.
        This is cached.
        """
        return np.array(list(self.data_dict.values()))

    @cached_property
    def labels(self) -> NDArray[np.str_]:
        """
        Get all labels in the dataset as an array.
        This is cached.
        """
        return np.array(list(self.data_dict.keys()))

    @cached_property
    def targets(self) -> NDArray[np.float64]:
        """
        Get all target points in the dataset as an array.
        This is cached.
        """
        msk = np.char.find(self.labels, "TARGET") >= 0
        return self.points[msk]

    @cached_property
    def target_labels(self) -> NDArray[np.str_]:
        """
        Get all target labels in the dataset as an array.
        This is cached.
        """
        msk = np.char.find(self.labels, "TARGET") >= 0
        return self.labels[msk]

    def copy(self) -> Self:
        """
        Make a deep copy of the dataset.

        Returns
        -------
        copy : Dataset
            A deep copy of this dataset.
        """
        return deepcopy(self)

labels cached property

Get all labels in the dataset as an array. This is cached.

points cached property

Get all points in the dataset as an array. This is cached.

target_labels cached property

Get all target labels in the dataset as an array. This is cached.

targets cached property

Get all target points in the dataset as an array. This is cached.

copy()

Make a deep copy of the dataset.

Returns:

Name Type Description
copy Dataset

A deep copy of this dataset.

Source code in lat_alignment/dataset.py
 97
 98
 99
100
101
102
103
104
105
106
def copy(self) -> Self:
    """
    Make a deep copy of the dataset.

    Returns
    -------
    copy : Dataset
        A deep copy of this dataset.
    """
    return deepcopy(self)

DatasetPhotogrammetry dataclass

Bases: Dataset

Container class for photogrammetry dataset. Provides a dict like interface for accessing points by their labels.

Attributes:

Name Type Description
data_dict dict[str, NDArray[float64]]

Dict of photogrammetry points. You should genrally not touch this directly.

Source code in lat_alignment/dataset.py
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
@dataclass
class DatasetPhotogrammetry(Dataset):
    """
    Container class for photogrammetry dataset.
    Provides a dict like interface for accessing points by their labels.

    Attributes
    ----------
    data_dict : dict[str, NDArray[np.float64]]
        Dict of photogrammetry points.
        You should genrally not touch this directly.
    """

    def _clear_cache(self):
        self.__dict__.pop("points", None)
        self.__dict__.pop("labels", None)
        self.__dict__.pop("codes", None)
        self.__dict__.pop("code_labels", None)
        self.__dict__.pop("target", None)
        self.__dict__.pop("target_labels", None)

    def __setattr__(self, name, value):
        if name == "data_dict":
            self._clear_cache()
        return super().__setattr__(name, value)

    @cached_property
    def codes(self) -> NDArray[np.float64]:
        """
        Get all coded points in the dataset as an array.
        This is cached.
        """
        msk = np.char.find(self.labels, "CODE") >= 0
        return self.points[msk]

    @cached_property
    def code_labels(self) -> NDArray[np.str_]:
        """
        Get all coded labels in the dataset as an array.
        This is cached.
        """
        msk = np.char.find(self.labels, "CODE") >= 0
        return self.labels[msk]

    def copy(self) -> Self:
        """
        Make a deep copy of the dataset.

        Returns
        -------
        copy : Dataset
            A deep copy of this dataset.
        """
        return deepcopy(self)

code_labels cached property

Get all coded labels in the dataset as an array. This is cached.

codes cached property

Get all coded points in the dataset as an array. This is cached.

copy()

Make a deep copy of the dataset.

Returns:

Name Type Description
copy Dataset

A deep copy of this dataset.

Source code in lat_alignment/dataset.py
260
261
262
263
264
265
266
267
268
269
def copy(self) -> Self:
    """
    Make a deep copy of the dataset.

    Returns
    -------
    copy : Dataset
        A deep copy of this dataset.
    """
    return deepcopy(self)

DatasetReference dataclass

Bases: Dataset

Container class for dataset that only contains reference points and their errors. Provides a dict like interface for accessing points by their labels. Note that this class doesn't cover edge cases from misuse, use at your own risk.

Attributes:

Name Type Description
data_dict dict[str, NDArray[float64]]

Dict of data points. You should genrally not touch this directly.

Source code in lat_alignment/dataset.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
@dataclass
class DatasetReference(Dataset):
    """
    Container class for dataset that only contains reference points and their errors.
    Provides a dict like interface for accessing points by their labels.
    Note that this class doesn't cover edge cases from misuse, use at your own risk.

    Attributes
    ----------
    data_dict : dict[str, NDArray[np.float64]]
        Dict of data points.
        You should genrally not touch this directly.
    """

    def _clear_cache(self):
        self.__dict__.pop("points", None)
        self.__dict__.pop("labels", None)
        self.__dict__.pop("elem_names", None)
        self.__dict__.pop("elem_labels", None)
        self.__dict__.pop("ref_labels", None)
        self.__dict__.pop("err_labels", None)
        self.__dict__.pop("elements", None)
        self.__dict__.pop("reference", None)
        self.__dict__.pop("errors", None)

    def __setattr__(self, name, value):
        if name == "data_dict":
            self._clear_cache()
        return super().__setattr__(name, value)

    def __setitem__(self, key, item):
        if key in self.elem_names:
            if item.shape != self.elements[key].shape:
                raise ValueError(
                    "Can't set {key} with shape {item.shape} when original shape is {self.elements[key]}"
                )
            for i, l in enumerate(self.elem_labels[key]):
                self.data_dict[l] = item[i]
        elif key[:-4] in self.elem_names and "_ref" in key:
            if item.shape != self.reference[key[:-4]].shape:
                raise ValueError(
                    "Can't set {key} with shape {item.shape} when original shape is {self.reference[key]}"
                )
            for i, l in enumerate(self.ref_labels[key[:-4]]):
                self.data_dict[l] = item[i]
        elif key[:-4] in self.elem_names and "_err" in key:
            if item.shape != self.errors[key[:-4]].shape:
                raise ValueError(
                    "Can't set {key} with shape {item.shape} when original shape is {self.error[key]}"
                )
            for i, l in enumerate(self.err_labels[key[:-4]]):
                self.data_dict[l] = item[i]
        else:
            self.data_dict[key] = item
        self._clear_cache()

    @cached_property
    def elem_names(self) -> list[str]:
        return np.unique([k.split("_")[0] for k in self.labels]).tolist()

    @cached_property
    def elem_labels(self) -> dict[str, list[str]]:
        return {
            e: [
                k
                for k in self.labels
                if (e in k and k[-4:] != "_ref" and k[-4:] != "_err")
            ]
            for e in self.elem_names
        }

    @cached_property
    def elements(self) -> dict[str, NDArray[np.float64]]:
        return {
            e: np.array([self.data_dict[k] for k in self.elem_labels[e]])
            for e in self.elem_names
        }

    @cached_property
    def ref_labels(self) -> dict[str, list[str]]:
        return {
            e: [k for k in self.labels if (e in k and k[-4:] == "_ref")]
            for e in self.elem_names
        }

    @cached_property
    def reference(self) -> dict[str, NDArray[np.float64]]:
        return {
            e: np.array([self.data_dict[k] for k in self.ref_labels[e]])
            for e in self.elem_names
        }

    @cached_property
    def err_labels(self) -> dict[str, list[str]]:
        return {
            e: [k for k in self.labels if (e in k and k[-4:] == "_err")]
            for e in self.elem_names
        }

    @cached_property
    def errors(self) -> dict[str, NDArray[np.float64]]:
        return {
            e: np.array([self.data_dict[k] for k in self.err_labels[e]])
            for e in self.elem_names
        }