Repository: xCDAT/xcdat

Issue:
[Bug]: Converting the longitude axis orientation to the same system results in odd behaviors
### What happened?

> As a side note, there is some weird behavior here: the longitude axis goes from size 360 to 361 (and one set of lon_bnds 
> goes from 0 to 0). I'm not sure if this is specific to converting from one longitude coordinate system to the same system 
> (something people wouldn't normally do) or a more generic issue. This doesn't happen when converting to (-180, 180).
> &mdash; @pochedls from https://github.com/xCDAT/xcdat/pull/239#issuecomment-1146235781



### What did you expect to happen?

The coordinates and coordinate bounds should remain the same if attempting to convert to the same axis system.

Solution: Detect that the desired axis system is the same as the existing system, so use a `pass` statement to ignore.

### Minimal Complete Verifiable Example

_No response_

### Relevant log output

_No response_

### Anything else we need to know?

_No response_

### Environment

`main` branch of xcdat

Discussion:

Patch:
diff --git a/xcdat/axis.py b/xcdat/axis.py
index 55eac02..5d1a256 100644
--- a/xcdat/axis.py
+++ b/xcdat/axis.py
@@ -100,22 +100,22 @@ def swap_lon_axis(
         The Dataset with swapped lon axes orientation.
     """
     ds = dataset.copy()
-    lon: xr.DataArray = dataset.bounds._get_coords("lon").copy()
+    lon: xr.DataArray = _get_coord_var(ds, "X").copy()
     lon_bounds: xr.DataArray = dataset.bounds.get_bounds("lon").copy()
 
     with xr.set_options(keep_attrs=True):
         if to == (-180, 180):
-            lon = ((lon + 180) % 360) - 180
-            lon_bounds = ((lon_bounds + 180) % 360) - 180
-            ds = _reassign_lon(ds, lon, lon_bounds)
+            new_lon = ((lon + 180) % 360) - 180
+            new_lon_bounds = ((lon_bounds + 180) % 360) - 180
+            ds = _reassign_lon(ds, new_lon, new_lon_bounds)
         elif to == (0, 360):
-            lon = lon % 360
-            lon_bounds = lon_bounds % 360
-            ds = _reassign_lon(ds, lon, lon_bounds)
+            new_lon = lon % 360
+            new_lon_bounds = lon_bounds % 360
+            ds = _reassign_lon(ds, new_lon, new_lon_bounds)
 
             # Handle cases where a prime meridian cell exists, which can occur
             # after swapping to (0, 360).
-            p_meridian_index = _get_prime_meridian_index(lon_bounds)
+            p_meridian_index = _get_prime_meridian_index(new_lon_bounds)
             if p_meridian_index is not None:
                 ds = _align_lon_to_360(ds, p_meridian_index)
         else:
@@ -124,8 +124,13 @@ def swap_lon_axis(
                 "orientations."
             )
 
+    # If the swapped axis orientation is the same as the existing axis
+    # orientation, return the original Dataset.
+    if new_lon.identical(lon):
+        return dataset
+
     if sort_ascending:
-        ds = ds.sortby(lon.name, ascending=True)
+        ds = ds.sortby(new_lon.name, ascending=True)
 
     return ds
 


Test patch:
diff --git a/tests/test_axis.py b/tests/test_axis.py
index 1263ed8..abf0943 100644
--- a/tests/test_axis.py
+++ b/tests/test_axis.py
@@ -143,6 +143,32 @@ class TestSwapLonAxis:
         with pytest.raises(ValueError):
             swap_lon_axis(ds_180, to=(0, 360))
 
+    def test_does_not_swap_if_desired_orientation_is_the_same_as_the_existing_orientation(
+        self,
+    ):
+        ds_360 = xr.Dataset(
+            coords={
+                "lon": xr.DataArray(
+                    name="lon",
+                    data=np.array([60, 150, 271]),
+                    dims=["lon"],
+                    attrs={"units": "degrees_east", "axis": "X", "bounds": "lon_bnds"},
+                )
+            },
+            data_vars={
+                "lon_bnds": xr.DataArray(
+                    name="lon_bnds",
+                    data=np.array([[0, 120], [120, 181], [181, 360]]),
+                    dims=["lon", "bnds"],
+                    attrs={"is_generated": "True"},
+                )
+            },
+        )
+
+        result = swap_lon_axis(ds_360, to=(0, 360))
+
+        assert result.identical(ds_360)
+
     def test_swap_from_360_to_180_and_sorts(self):
         ds_360 = xr.Dataset(
             coords={