Repository: tomvothecoder/xcdat

Issue:
Axis attributes dropped after retrieving/generating bounds
I noticed that if I generate or retrieve axis bounds, some of the axis information is dropped. Ideally, all of the axis information should be retained when generating bounds. 

### What are the steps to reproduce this issue?
```import xarray as xr
from xcdat import axis

fn = '/p/css03/esgf_publish/CMIP6/CMIP/NCAR/CESM2/historical/r1i1p1f1/Amon/tas/gn/v20190308/tas_Amon_CESM2_historical_r1i1p1f1_gn_185001-201412.nc'
ds = xr.open_dataset(fn)
print(ds.lat.units)
```
> degrees_north
```
lat_bnds = ds.axis.get_bounds("lat", generate="True")
print(ds.lat.units)
```
> AttributeError: 'DataArray' object has no attribute 'units'

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo) Report
> Merging [#79](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo) (c7972fb) into [main](https://codecov.io/gh/tomvothecoder/xcdat/commit/4574f2155891ea8aaac3d2f1753b278cdbcad006?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo) (4574f21) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/tomvothecoder/xcdat/pull/79/graphs/tree.svg?width=650&height=150&src=pr&token=T8W41LN26O&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo)](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo)

```diff
@@            Coverage Diff            @@
##              main       #79   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         4           
  Lines          119       119           
=========================================
  Hits           119       119           
```


| [Impacted Files](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo) | Coverage Δ | |
|---|---|---|
| [xcdat/axis.py](https://codecov.io/gh/tomvothecoder/xcdat/pull/79/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo#diff-eGNkYXQvYXhpcy5weQ==) | `100.00% <ø> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo). Last update [4574f21...c7972fb](https://codecov.io/gh/tomvothecoder/xcdat/pull/79?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tom+Vo).

tomvothecoder: @pochedls Existing axis coords attributes should now be maintained after generating bounds when they don't exist. This bug didn't affect returning existing bounds.

I added a unit test to validate this behavior, but here's an ad-hoc test on real data:
```
import xarray as xr
from xcdat import axis

> ds = xr.open_dataset("./input/ts_Amon_ACCESS1-0_historical_r1i1p1_185001-200512.nc")
> ds.lat.attrs
{'bounds': 'lat_bnds',
 'units': 'degrees_north',
 'axis': 'Y',
 'long_name': 'latitude',
 'standard_name': 'latitude'}

# Drop existing lat bounds to generate new lat bounds
> ds = ds.drop("lat_bnds")
> lat_bnds = ds.axis.get_bounds("lat_bnds", allow_generating=True)
> ds.lat.attrs
{'bounds': 'lat_bnds',
 'units': 'degrees_north',
 'axis': 'Y',
 'long_name': 'latitude',
 'standard_name': 'latitude'}
```

pochedls: @tomvothecoder - this looks good to me. I thought this bug did affect files that had bounds, but that may have been because I was not using the most recent code base. I noticed that I had to change the flag `generate` to `allow_generating` (I prefer this and am glad the default is True). I am happy to have this merged!

Patch:
diff --git a/xcdat/axis.py b/xcdat/axis.py
index b31c071..c483e50 100644
--- a/xcdat/axis.py
+++ b/xcdat/axis.py
@@ -164,9 +164,9 @@ class AxisAccessor:
         self._dataset[var_name] = xr.DataArray(
             name=var_name,
             data=bounds,
-            coords={axis: axis_coords.data},
+            coords={axis: axis_coords},
             dims=[axis, "bnds"],
-            attrs={"units": axis_coords.units, "is_generated": True},
+            attrs={**axis_coords.attrs, "is_generated": True},
         )
         return self._dataset[var_name]
 


Test patch:
diff --git a/tests/test_axis.py b/tests/test_axis.py
index b38c31a..4bdee2c 100644
--- a/tests/test_axis.py
+++ b/tests/test_axis.py
@@ -17,7 +17,7 @@ class TestAxisAccessor:
         lon = xr.DataArray(
             data=np.array([0, 1.875, 356.25, 358.125]),
             dims=["lon"],
-            attrs={"units": "degrees_east", "axis": "x"},
+            attrs={"units": "degrees_east", "axis": "X"},
         )
 
         # Generated axes boundaries for assertions
@@ -26,9 +26,9 @@ class TestAxisAccessor:
             data=np.array(
                 [[-90, -89.375], [-89.375, 0.0], [0.0, 89.375], [89.375, 90]]
             ),
-            coords={"lat": lat.data},
+            coords={"lat": lat},
             dims=["lat", "bnds"],
-            attrs={"units": "degrees_north", "is_generated": True},
+            attrs={"units": "degrees_north", "axis": "Y", "is_generated": True},
         )
         self.lon_bnds = xr.DataArray(
             name="lon_bnds",
@@ -40,9 +40,9 @@ class TestAxisAccessor:
                     [357.1875, 359.0625],
                 ]
             ),
-            coords={"lon": lon.data},
+            coords={"lon": lon},
             dims=["lon", "bnds"],
-            attrs={"units": "degrees_east", "is_generated": True},
+            attrs={"units": "degrees_east", "axis": "X", "is_generated": True},
         )
 
         # Create Dataset using coordinates (for testing short axes names)
@@ -98,6 +98,17 @@ class TestAxisAccessor:
         with pytest.raises(ValueError):
             obj.get_bounds("incorrect_axis_argument")  # type: ignore
 
+    def test__get_bounds_does_not_drop_attrs_of_existing_coords_when_generating_bounds(
+        self,
+    ):
+        ds = self.ds.copy()
+
+        lat_bnds = ds.axis.get_bounds("lat", allow_generating=True)
+        assert lat_bnds.equals(self.lat_bnds)
+        ds = ds.drop("lat_bnds")
+
+        assert ds.identical(self.ds)
+
     def test__gen_bounds_raises_errors(self):
         obj = AxisAccessor(self.ds)
 
@@ -111,7 +122,7 @@ class TestAxisAccessor:
             obj._dataset.lat.attrs["units"] = "incorrect_value"
             obj._gen_bounds("lat")
 
-    def test__gen_bounds_for_short_axis_name(self):
+    def test__gen_bounds_returns_bnds(self):
         obj = AxisAccessor(self.ds)
 
         lat_bnds = obj._gen_bounds("lat")