| 1535 | return None |
| 1536 | |
| 1537 | def sel( |
| 1538 | self, labels: dict[Any, Any], method=None, tolerance=None |
| 1539 | ) -> IndexSelResult: |
| 1540 | from xarray.core.dataarray import DataArray |
| 1541 | from xarray.core.variable import Variable |
| 1542 | |
| 1543 | if method != "nearest": |
| 1544 | raise ValueError( |
| 1545 | "CoordinateTransformIndex only supports selection with method='nearest'" |
| 1546 | ) |
| 1547 | |
| 1548 | labels_set = set(labels) |
| 1549 | coord_names_set = set(self.transform.coord_names) |
| 1550 | |
| 1551 | missing_labels = coord_names_set - labels_set |
| 1552 | if missing_labels: |
| 1553 | missing_labels_str = ",".join([f"{name}" for name in missing_labels]) |
| 1554 | raise ValueError(f"missing labels for coordinate(s): {missing_labels_str}.") |
| 1555 | |
| 1556 | labels = { |
| 1557 | name: Variable(dims=(name,), data=data) |
| 1558 | if isinstance(data, np.ndarray) |
| 1559 | else data |
| 1560 | for (name, data) in labels.items() |
| 1561 | } |
| 1562 | |
| 1563 | label0_obj = next(iter(labels.values())) |
| 1564 | dim_size0 = getattr(label0_obj, "sizes", {}) |
| 1565 | |
| 1566 | is_xr_obj = [ |
| 1567 | isinstance(label, DataArray | Variable) for label in labels.values() |
| 1568 | ] |
| 1569 | if not all(is_xr_obj): |
| 1570 | raise TypeError( |
| 1571 | "CoordinateTransformIndex only supports advanced (point-wise) indexing " |
| 1572 | "with either xarray.DataArray or xarray.Variable objects." |
| 1573 | ) |
| 1574 | dim_size = [getattr(label, "sizes", {}) for label in labels.values()] |
| 1575 | if any(ds != dim_size0 for ds in dim_size): |
| 1576 | raise ValueError( |
| 1577 | "CoordinateTransformIndex only supports advanced (point-wise) indexing " |
| 1578 | "with xarray.DataArray or xarray.Variable objects of matching dimensions." |
| 1579 | ) |
| 1580 | |
| 1581 | coord_labels = { |
| 1582 | name: labels[name].values for name in self.transform.coord_names |
| 1583 | } |
| 1584 | dim_positions = self.transform.reverse(coord_labels) |
| 1585 | |
| 1586 | results: dict[str, Variable | DataArray] = {} |
| 1587 | dims0 = tuple(dim_size0) |
| 1588 | for dim, pos in dim_positions.items(): |
| 1589 | # TODO: rounding the decimal positions is not always the behavior we expect |
| 1590 | # (there are different ways to represent implicit intervals) |
| 1591 | # we should probably make this customizable. |
| 1592 | pos = np.round(pos).astype("int") |
| 1593 | if isinstance(label0_obj, Variable): |
| 1594 | results[dim] = Variable(dims0, pos) |