Repository: neuromodulation/py_neuromodulation (language: python)

Issue:
Write function for testing settings.json 
Write a function, that checks if settings.json has been specified correctly by the user. 
Especially for real-time analysis it could be very important to check this because we don't want to launch an online recording with an error in the settings.


Discussion / hints:

Fix patch:
diff --git a/pyneuromodulation/settings.py b/pyneuromodulation/settings.py
new file mode 100644
index 00000000..f7a9fd93
--- /dev/null
+++ b/pyneuromodulation/settings.py
@@ -0,0 +1,69 @@
+import json
+from os.path import isdir
+
+
+def test_settings(settings, verbose=True):
+    """Test if settings are specified correctly in settings.json
+
+    Parameters
+    ----------
+    settings: dict, string or path
+        settings loaded as dictionary, or string/path pointing to settings.json.
+    verbose: boolean
+        set to True if feedback is desired.
+    Returns
+    -------
+    None
+    """
+    if isinstance(settings, dict):
+        s = settings
+    else:
+        with open(settings, encoding='utf-8') as json_file:
+            s = json.load(json_file)
+        assert (isinstance(s, dict))
+
+    assert (isdir(s["BIDS_path"]))
+    assert (isdir(s["out_path"]))
+    assert (isinstance(s["resampling_rate"], (float, int)))
+    assert (isinstance(s["max_dist_cortex"], (float, int)))
+    assert (isinstance(s["max_dist_subcortex"], (float, int)))
+    assert (isinstance(value, bool) for value in s["methods"].values()), \
+        "Methods must be a boolean value."
+    assert (any(value is True for value in s["methods"].values())), \
+        "Set at least one method to True."
+    if s["methods"]["normalization"] is True:
+        assert (isinstance(s["normalization_settings"]["normalization_time"],
+                (float, int)))
+        assert (s["normalization_settings"]["normalization_method"] in [
+            "mean", "median"])
+    if s["methods"]["kalman_filter"] is True:
+        assert (isinstance(s["kalman_filter_settings"]["Tp"], (float, int)))
+        assert (isinstance(s["kalman_filter_settings"]["sigma_w"],
+                           (float, int)))
+        assert (isinstance(s["kalman_filter_settings"]["sigma_v"],
+                           (float, int)))
+        assert (isinstance(s["kalman_filter_settings"]["frequency_bands"],
+                           list)), "Frequency bands for Kalman filter must " \
+                                   "be specified as a list."
+        assert (s["kalman_filter_settings"]["frequency_bands"]), \
+            "No frequency bands specified for Kalman filter."
+    if s["methods"]["bandpass_filter"] is True:
+        keys = ["feature_labels", "frequency_ranges", "segment_lengths"]
+        lists = [s["bandpass_filter_settings"][key] for key in keys]
+        assert (isinstance(lis, list) for lis in lists)
+        assert (len(lists[0]) == len(lists[1]) == len(lists[2]))
+        assert (isinstance(value, bool) for value in s[
+            "bandpass_filter_settings"]["bandpower_features"].values())
+        assert (any(value is True for value in s["bandpass_filter_settings"][
+            "bandpower_features"].values())), "Set at least one " \
+                                              "bandpower_feature to True."
+    if s["methods"]["sharpwave_analysis"] is True:
+        assert (isinstance(s["sharpwave_analysis_settings"][
+                               "filter_low_cutoff"], (int, float)))
+        assert (isinstance(s["sharpwave_analysis_settings"][
+                               "filter_high_cutoff"], (int, float)))
+        assert (s["sharpwave_analysis_settings"]["filter_high_cutoff"] >
+                s["sharpwave_analysis_settings"]["filter_low_cutoff"])
+    if verbose:
+        print("No Error occurred when checking the settings.")
+    return


Test patch:
diff --git a/pyneuromodulation/tests/test_rereference.py b/pyneuromodulation/tests/test.py
similarity index 95%
rename from pyneuromodulation/tests/test_rereference.py
rename to pyneuromodulation/tests/test.py
index 5b965e0a..08c1fff0 100644
--- a/pyneuromodulation/tests/test_rereference.py
+++ b/pyneuromodulation/tests/test.py
@@ -1,5 +1,6 @@
 import json
 import os
+from os.path import isdir
 import sys
 
 from threading import main_thread
@@ -16,6 +17,7 @@
 import define_M1
 import generator
 import rereference
+import settings
 
 
 def read_example_data(PATH_PYNEUROMODULATION):
@@ -111,8 +113,11 @@ def test_rereference(ref_here, ieeg_batch, df_M1):
         assert_array_equal(ref_dat[bp_reref_idx,:], \
                         ieeg_batch[bp_reref_idx,:] - ieeg_batch[referenced_bp_channel,:])
 
+
 if __name__ == "__main__":
 
     ieeg_batch, df_M1 = read_example_data(PATH_PYNEUROMODULATION)
     ref_here = initialize_rereference(df_M1)
-    test_rereference(ref_here, ieeg_batch, df_M1)
\ No newline at end of file
+    test_rereference(ref_here, ieeg_batch, df_M1)
+    settings.test_settings(os.path.join(PATH_PYNEUROMODULATION, 'examples',
+                                        'settings.json'))
\ No newline at end of file