Repository: British-Oceanographic-Data-Centre/COAsT (language: python)

Issue:
DEBUG -> CRITICAL
I have change DEBUG to CRITICAL in unit_test.py and logging_util.py. I have also added two lines to __init__.py in order to set a logging default on import.

This should greatly reduce the output but still allow for the level to be changed if needed.

Also sneaking in some updates to docstrings in tidegauge_multiple.


Discussion / hints:

Fix patch:
diff --git a/coast/__init__.py b/coast/__init__.py
index 393cf630..2b9d8db8 100644
--- a/coast/__init__.py
+++ b/coast/__init__.py
@@ -23,3 +23,8 @@
 from .tidegauge import Tidegauge
 from .tidegauge_multiple import TidegaugeMultiple
 from .config_parser import ConfigParser
+
+# Set default for logging level when coast is imported
+import logging
+
+logging_util.setup_logging(level=logging.CRITICAL)
diff --git a/coast/logging_util.py b/coast/logging_util.py
index e2c95cf6..296c22e2 100644
--- a/coast/logging_util.py
+++ b/coast/logging_util.py
@@ -9,7 +9,7 @@
 DEFAULT_FORMAT = "%(asctime)s %(levelname)s %(message)s"
 
 
-def get_logger(name: str = None, level: int = logging.DEBUG):
+def get_logger(name: str = None, level: int = logging.CRITICAL):
     logger = logging.getLogger(name=name)
     logger.setLevel(level)
     return logger
@@ -25,7 +25,7 @@ def create_handler(logger: logging.Logger, stream: io.TextIOWrapper = sys.stdout
 
 def setup_logging(
     name: str = None,
-    level: int = logging.DEBUG,
+    level: int = logging.CRITICAL,
     stream: io.TextIOWrapper = sys.stdout,
     format_string: str = DEFAULT_FORMAT,
 ):
diff --git a/coast/tidegauge_multiple.py b/coast/tidegauge_multiple.py
index b00d2762..23a8033e 100644
--- a/coast/tidegauge_multiple.py
+++ b/coast/tidegauge_multiple.py
@@ -146,7 +146,6 @@ def harmonic_analysis_utide(
                 continue
 
             if (n_time - number_of_nan) < min_datapoints:
-                print(sum(~np.isnan(ssh.values)))
                 analyses.append([])
                 continue
 
@@ -167,7 +166,14 @@ def harmonic_analysis_utide(
         return analyses
 
     def reconstruct_tide_utide(self, utide_solution_list, constit=None):
-        """ """
+        """
+        Use the time information inside this object to construct a tidal time
+        series using a list of utide analysis objects. This list can be obtained
+        using harmonic_analysis_utide(). Specify constituents to use in the
+        reconstruction by passing a list of strings such as 'M2' to the constit
+        argument. This won't work if a specified constituent is not present in
+        the analysis.
+        """
 
         ds = self.dataset
         n_port = ds.dims["id"]
@@ -196,6 +202,13 @@ def reconstruct_tide_utide(self, utide_solution_list, constit=None):
         return tg_return
 
     def calculate_residuals(self, tg_tide, apply_filter=True, window_length=25, polyorder=3):
+        """
+        Calculate non tidal residuals using the Total water level in THIS object
+        and the tide data in another object. This assumes that this object
+        contains a 'ssh' variable and the tide object contains a 'ssh_tide'
+        variable. This tide variable can be constructed using e.g.
+        reconstruct_tide_utide().
+        """
 
         # NTR: Calculate non tidal residuals
         ntr = self.dataset.ssh - tg_tide.dataset.ssh_tide
@@ -214,6 +227,29 @@ def calculate_residuals(self, tg_tide, apply_filter=True, window_length=25, poly
         return tg_return
 
     def threshold_statistics(self, thresholds=np.arange(-0.4, 2, 0.1), peak_separation=12):
+        """
+        Do some threshold statistics for all variables with a time dimension
+        inside this tidegauge_multiple object. Specifically, this routine will
+        calculate:
+
+                peak_count          : The number of indepedent peaks over
+                                      each specified threshold. Independent peaks
+                                      are defined using the peak_separation
+                                      argument. This is the number of datapoints
+                                      either side of a peak within which data
+                                      is ommited for further peak search.
+                time_over_threshold : The total time spent over each threshold
+                                      This is NOT an integral, but simple a count
+                                      of all points over threshold.
+                dailymax_count      : A count of the number of daily maxima over
+                                      each threshold
+                monthlymax_count    : A count of the number of monthly maxima
+                                      over each threshold.
+
+        Output is a xarray dataset containing analysed variables. The name of
+        each analysis variable is constructed using the original variable name
+        and one of the above analysis categories.
+        """
 
         ds = self.dataset
         ds_thresh = xr.Dataset(ds[list(ds.coords.keys())])
@@ -225,15 +261,13 @@ def threshold_statistics(self, thresholds=np.arange(-0.4, 2, 0.1), peak_separati
         for vv in var_list:
 
             empty_thresh = np.zeros((n_port, n_thresholds)) * np.nan
-            ds_thresh["peak_count_" + vv] = (["id", "threshold"], empty_thresh)
-            ds_thresh["time_over_threshold_" + vv] = (["id", "threshold"], empty_thresh)
-            ds_thresh["dailymax_count_" + vv] = (["id", "threshold"], empty_thresh)
-            ds_thresh["monthlymax_count_" + vv] = (["id", "threshold"], empty_thresh)
+            ds_thresh["peak_count_" + vv] = (["id", "threshold"], np.array(empty_thresh))
+            ds_thresh["time_over_threshold_" + vv] = (["id", "threshold"], np.array(empty_thresh))
+            ds_thresh["dailymax_count_" + vv] = (["id", "threshold"], np.array(empty_thresh))
+            ds_thresh["monthlymax_count_" + vv] = (["id", "threshold"], np.array(empty_thresh))
 
             for pp in range(n_port):
 
-                print(pp)
-
                 # Identify NTR peaks for threshold analysis
                 data_pp = ds[vv].isel(id=pp)
                 if np.sum(np.isnan(data_pp.values)) == ds.dims["t_dim"]:
@@ -267,10 +301,23 @@ def threshold_statistics(self, thresholds=np.arange(-0.4, 2, 0.1), peak_separati
         return ds_thresh
 
     def demean_timeseries(self):
+        """
+        Subtract time means from all variables within this tidegauge_multiple
+        object. This is done independently for each id location.
+        """
         return self.dataset - self.dataset.mean(dim="t_dim")
 
     def obs_operator(self, gridded, time_interp="nearest"):
-        """ """
+        """
+        Regrids a Gridded object onto a tidegauge_multiple object. A nearest
+        neighbour interpolation is done for spatial interpolation and time
+        interpolation can be specified using the time_interp argument. This
+        takes any scipy interpolation string. If Gridded object contains a
+        landmask variables, then the nearest WET point is taken for each tide
+        gauge.
+
+        Output is a new tidegauge_multiple object containing interpolated data.
+        """
 
         gridded = gridded.dataset
         ds = self.dataset
@@ -310,6 +357,19 @@ def obs_operator(self, gridded, time_interp="nearest"):
         return tg_out
 
     def difference(self, other, absolute_diff=True, square_diff=True):
+        """
+        Calculates differences between two tide gauge objects. Will calculate
+        differences, absolute differences and square differences between all
+        common variables within each object. Each object should have the same
+        sized dimensions. When calling this routine, the differencing is done
+        as follows:
+
+            dataset1.difference(dataset2)
+
+        This will do dataset1 - dataset2.
+
+        Output is a new tidegauge object containing differenced variables.
+        """
 
         differenced = self.dataset - other.dataset
         diff_vars = list(differenced.keys())
diff --git a/setup.py b/setup.py
index db324095..28f6be81 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@
 PACKAGE = SimpleNamespace(
     **{
         "name": "COAsT",
-        "version": "1.2.5",
+        "version": "1.2.6",
         "description": "This is the Coast Ocean Assessment Tool",
         "url": "https://www.bodc.ac.uk",
         "download_url": "https://github.com/British-Oceanographic-Data-Centre/COAsT/",


Test patch:
diff --git a/unit_testing/unit_test.py b/unit_testing/unit_test.py
index db001f2f..e6623a64 100755
--- a/unit_testing/unit_test.py
+++ b/unit_testing/unit_test.py
@@ -56,7 +56,7 @@
 """
 ## Initialise logging and save to log file
 log_file = open("unit_testing/unit_test.log", "w")  # Need log_file.close()
-coast.logging_util.setup_logging(stream=log_file, level=logging.DEBUG)
+coast.logging_util.setup_logging(stream=log_file, level=logging.CRITICAL)
 ## Alternative logging levels
 # ..., level=logging.DEBUG) # Detailed information, typically of interest only when diagnosing problems.
 # ..., level=logging.INFO) # Confirmation that things are working as expected.