Repository: osoceanacoustics/echopype
Issue: Merged Echodata saved file does not have the proper encoding

## Overview

After merging echodata objects into a single echodata, performing a `to_netcdf` on that objects results in an incorrect encoding of time variable.

## To reproduce

Below example assumes that the test_data has been retrieved from the docker image or google drive.

```python
import echopype as ep

ed0 = ep.open_raw('./echopype/test_data/ek60/ncei-wcsd/Summer2017-D20170719-T203615.raw', sonar_model='ek60')

ed0.to_netcdf('./test.nc', overwrite=True)

ed1 = ep.open_raw('./echopype/test_data/ek60/ncei-wcsd/Summer2017-D20170719-T205415.raw', sonar_model='ek60')

all_ed = ep.combine_echodata([ed0, ed1])

all_ed.to_netcdf('./combined.nc', overwrite=True)
```

Now investigating the files with ncdump. Note that below pasted results are truncated.

1. Single echodata output

    ```bash
    ncdump -h test.nc
    ```
    
    Results in
    
    ```
    ...
    group: Environment {
      dimensions:
  	    frequency = 3 ;
  	    ping_time = 535 ;
      variables:
            ...
  	    double ping_time(ping_time) ;
  		    ping_time:_FillValue = NaN ;
  		    ping_time:axis = "T" ;
  		    ping_time:long_name = "Timestamps for NMEA position datagrams" ;
  		    ping_time:standard_name = "time" ;
  		    ping_time:units = "seconds since 1900-01-01T00:00:00+00:00" ;
  		    ping_time:calendar = "gregorian" ;
      } // group Environment
    ...
    ```

2. Merged echodata output

    ```bash
    ncdump -h combined.nc
    ```
    
    Results in
    
    ```
    ...
    group: Environment {
        dimensions:
  	      frequency = 3 ;
  	      ping_time = 1069 ;
        variables:
  	      ...
  	      int64 ping_time(ping_time) ;
  		      ping_time:axis = "T" ;
  		      ping_time:long_name = "Timestamps for NMEA position datagrams" ;
  		      ping_time:standard_name = "time" ;
  		      ping_time:units = "nanoseconds since 2017-07-19 20:36:15.952000" ;
  		      ping_time:calendar = "proleptic_gregorian" ;
        } // group Environment
    ...
    ```

Changed files:
echopype/echodata/combine.py, echopype/tests/echodata/test_echodata_combine.py

diff --git a/echopype/echodata/combine.py b/echopype/echodata/combine.py
index f8991bf..f1493be 100644
--- a/echopype/echodata/combine.py
+++ b/echopype/echodata/combine.py
@@ -8,6 +8,7 @@ from _echopype_version import version as ECHOPYPE_VERSION
 
 from ..core import SONAR_MODELS
 from ..qc import coerce_increasing_time, exist_reversed_time
+from ..utils.coding import set_encodings
 from .echodata import EchoData
 
 
@@ -247,6 +248,8 @@ def combine_echodata(echodatas: List[EchoData], combine_attrs="override") -> Ech
         if combined_group is not None:
             # xarray inserts this dimension when concating along multiple dimensions
             combined_group = combined_group.drop_dims("concat_dim", errors="ignore")
+
+        combined_group = set_encodings(combined_group)
         setattr(result, group, combined_group)
 
     # save ping time before reversal correction
diff --git a/echopype/tests/echodata/test_echodata_combine.py b/echopype/tests/echodata/test_echodata_combine.py
index 599a42b..b0eded7 100644
--- a/echopype/tests/echodata/test_echodata_combine.py
+++ b/echopype/tests/echodata/test_echodata_combine.py
@@ -8,6 +8,7 @@ from xarray.core.merge import MergeError
 
 import echopype
 from echopype.testing import TEST_DATA_FOLDER
+from echopype.utils.coding import DEFAULT_ENCODINGS
 from echopype.qc import exist_reversed_time
 from echopype.core import SONAR_MODELS
 
@@ -75,7 +76,9 @@ def test_combine_echodata(
             continue
         combined_group: xr.Dataset = getattr(combined, group_name)
         eds_groups = [
-            getattr(ed, group_name) for ed in eds if getattr(ed, group_name) is not None
+            getattr(ed, group_name)
+            for ed in eds
+            if getattr(ed, group_name) is not None
         ]
 
         def union_attrs(datasets: List[xr.Dataset]) -> Dict[str, Any]:
@@ -92,7 +95,9 @@ def test_combine_echodata(
         test_ds = xr.combine_nested(
             eds_groups,
             [concat_dims.get(group_name, concat_dims["default"])],
-            data_vars=concat_data_vars.get(group_name, concat_data_vars["default"]),
+            data_vars=concat_data_vars.get(
+                group_name, concat_data_vars["default"]
+            ),
             coords="minimal",
             combine_attrs="drop",
         )
@@ -106,10 +111,17 @@ def test_combine_echodata(
                 "location_time",
             ],
             errors="ignore",
-        ).drop_dims([f"{group}_attrs" for group in combined.group_map], errors="ignore")
+        ).drop_dims(
+            [f"{group}_attrs" for group in combined.group_map], errors="ignore"
+        )
         assert combined_group is None or test_ds.identical(
             combined_group.drop_dims(
-                ["old_ping_time", "ping_time", "old_location_time", "location_time"],
+                [
+                    "old_ping_time",
+                    "ping_time",
+                    "old_location_time",
+                    "location_time",
+                ],
                 errors="ignore",
             )
         )
@@ -117,7 +129,8 @@ def test_combine_echodata(
 
 def test_ping_time_reversal():
     eds = [
-        echopype.open_raw(file, "EK60") for file in ek60_reversed_ping_time_test_data
+        echopype.open_raw(file, "EK60")
+        for file in ek60_reversed_ping_time_test_data
     ]
     combined = echopype.combine_echodata(eds, "overwrite_conflicts")  # type: ignore
 
@@ -129,7 +142,10 @@ def test_ping_time_reversal():
                 assert not exist_reversed_time(combined_group, "ping_time")
             if "old_ping_time" in combined_group:
                 assert exist_reversed_time(combined_group, "old_ping_time")
-            if "location_time" in combined_group and group_name not in ("provenance", "nmea"):
+            if "location_time" in combined_group and group_name not in (
+                "provenance",
+                "nmea",
+            ):
                 assert not exist_reversed_time(combined_group, "location_time")
             if "old_location_time" in combined_group:
                 assert exist_reversed_time(combined_group, "old_location_time")
@@ -141,16 +157,18 @@ def test_ping_time_reversal():
 
 def test_attr_storage():
     # check storage of attributes before combination in provenance group
-    eds = [
-        echopype.open_raw(file, "EK60") for file in ek60_test_data
-    ]
+    eds = [echopype.open_raw(file, "EK60") for file in ek60_test_data]
     combined = echopype.combine_echodata(eds, "overwrite_conflicts")  # type: ignore
     for group in combined.group_map:
         if f"{group}_attrs" in combined.provenance:
             group_attrs = combined.provenance[f"{group}_attrs"]
             for i, ed in enumerate(eds):
                 for attr, value in getattr(ed, group).attrs.items():
-                    assert str(group_attrs.isel(echodata_filename=i).sel({f"{group}_attr_key": attr}).data[()]) == str(value)
+                    assert str(
+                        group_attrs.isel(echodata_filename=i)
+                        .sel({f"{group}_attr_key": attr})
+                        .data[()]
+                    ) == str(value)
 
     # check selection by echodata_filename
     for file in ek60_test_data:
@@ -158,14 +176,17 @@ def test_attr_storage():
     for group in combined.group_map:
         if f"{group}_attrs" in combined.provenance:
             group_attrs = combined.provenance[f"{group}_attrs"]
-            assert np.array_equal(group_attrs.sel(echodata_filename=Path(ek60_test_data[0]).name), group_attrs.isel(echodata_filename=0))
+            assert np.array_equal(
+                group_attrs.sel(
+                    echodata_filename=Path(ek60_test_data[0]).name
+                ),
+                group_attrs.isel(echodata_filename=0),
+            )
 
 
 def test_combine_attrs():
     # check parameter passed to combine_echodata that controls behavior of attribute combination
-    eds = [
-        echopype.open_raw(file, "EK60") for file in ek60_test_data
-    ]
+    eds = [echopype.open_raw(file, "EK60") for file in ek60_test_data]
     eds[0].beam.attrs.update({"foo": 1})
     eds[1].beam.attrs.update({"foo": 2})
     eds[2].beam.attrs.update({"foo": 3})
@@ -202,3 +223,25 @@ def test_combine_attrs():
 
     combined = echopype.combine_echodata(eds, "no_conflicts")  # type: ignore
     assert combined.beam.attrs["foo"] == 1
+
+
+def test_combined_encodings():
+    eds = [echopype.open_raw(file, "EK60") for file in ek60_test_data]
+    combined = echopype.combine_echodata(eds, "overwrite_conflicts")  # type: ignore
+
+    group_checks = []
+    for group in combined.group_map:
+        ds = getattr(combined, group)
+        if ds is not None:
+            for k, v in ds.variables.items():
+                if k in DEFAULT_ENCODINGS:
+                    encoding = ds[k].encoding
+                    if encoding != DEFAULT_ENCODINGS[k]:
+                        group_checks.append(
+                            f"  {combined.group_map[group]['name']}::{k}"
+                        )
+
+    if len(group_checks) > 0:
+        all_messages = ['Encoding mismatch found!'] + group_checks
+        message_text = '\\n'.join(all_messages)
+        raise AssertionError(message_text)