From 92c1e56d6cdcd79faa89343847beef08b8ed5554 Mon Sep 17 00:00:00 2001
From: David Fairbrother <DavidFair@users.noreply.github.com>
Date: Tue, 29 Nov 2016 16:25:36 +0000
Subject: [PATCH] Re #18108 Read from basic setup config file

---
 scripts/Diffraction/isis_powder/pearl.py      |  4 +-
 scripts/Diffraction/isis_powder/polaris.py    | 51 +++++++++++++++----
 .../polaris_routines/basic_config.yaml        |  9 ++++
 .../polaris_routines/polaris_calib_parser.py  |  1 -
 .../polaris_routines/polaris_calibration.yaml | 15 +++++-
 .../polaris_routines/polaris_config_parser.py | 24 +++++++++
 .../isis_powder/routines/common.py            | 18 +++++--
 7 files changed, 103 insertions(+), 19 deletions(-)
 create mode 100644 scripts/Diffraction/isis_powder/polaris_routines/basic_config.yaml
 create mode 100644 scripts/Diffraction/isis_powder/polaris_routines/polaris_config_parser.py

diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py
index e571079e609..1f37b5af1b9 100644
--- a/scripts/Diffraction/isis_powder/pearl.py
+++ b/scripts/Diffraction/isis_powder/pearl.py
@@ -65,9 +65,6 @@ class Pearl(AbstractInst):
     def _get_lambda_range(self):
         return self._lambda_lower, self._lambda_upper
 
-
-    # Methods #
-
     def get_run_details(self, run_number):
         # TODO once we migrate this to another format (i.e. not the if/elif/else) implement cached val
         cycle_dict = self._get_cycle_factory_dict(run_number=run_number)
@@ -77,6 +74,7 @@ class Pearl(AbstractInst):
         run_details.instrument_version = cycle_dict["instrument_version"]
         return run_details
 
+    @staticmethod
     def _get_cycle_factory_dict(self, run_number):
         # TODO remove this when we move to combining CAL/RUN factories
         run_input = ""
diff --git a/scripts/Diffraction/isis_powder/polaris.py b/scripts/Diffraction/isis_powder/polaris.py
index 8145cc3be74..7c8ee08e6fd 100644
--- a/scripts/Diffraction/isis_powder/polaris.py
+++ b/scripts/Diffraction/isis_powder/polaris.py
@@ -6,8 +6,7 @@ import mantid.simpleapi as mantid
 
 import isis_powder.routines.common as common
 from isis_powder.abstract_inst import AbstractInst
-from isis_powder.polaris_routines import polaris_algs, polaris_output
-from isis_powder.routines.RunDetails import RunDetails
+from isis_powder.polaris_routines import polaris_algs, polaris_config_parser, polaris_output
 
 
 class Polaris(AbstractInst):
@@ -15,17 +14,20 @@ class Polaris(AbstractInst):
     _masking_file_name = "VanaPeaks.dat"
     _number_of_banks = 5
 
-    def __init__(self, user_name, chopper_on, apply_solid_angle=True,
-                 calibration_dir=None, output_dir=None, **kwargs):
+    def __init__(self, chopper_on, config_file=None, **kwargs):
+
+        _set_kwargs_from_basic_config_file(config_path=config_file, kwargs=kwargs)
+
+        # Have to pass in everything through named types until abstract_inst takes kwargs
+        super(Polaris, self).__init__(user_name=kwargs["user_name"], calibration_dir=kwargs["calibration_directory"],
+                                      output_dir=kwargs["output_directory"], kwargs=kwargs)
 
-        super(Polaris, self).__init__(user_name=user_name, calibration_dir=calibration_dir,
-                                      output_dir=output_dir, kwargs=kwargs)
         self._chopper_on = chopper_on
-        self._apply_solid_angle = apply_solid_angle
+        self._apply_solid_angle = kwargs["apply_solid_angle"]
 
         self._spline_coeff = 100
 
-        # Caches the last dictionary to avoid us having to keep parsing the YAML
+        # Hold the last dictionary later to avoid us having to keep parsing the YAML
         self._run_details_last_run_number = None
         self._run_details_cached_obj = None
 
@@ -42,11 +44,11 @@ class Polaris(AbstractInst):
                                                  do_absorb_corrections=do_absorb_corrections,
                                                  gen_absorb_correction=gen_absorb_correction)
 
-    # Abstract implementation
-
     def get_default_group_names(self):
         return self._calibration_grouping_names
 
+    # Abstract implementation
+
     def get_run_details(self, run_number):
         if self._run_details_last_run_number == run_number:
             return self._run_details_cached_obj
@@ -132,3 +134,32 @@ class Polaris(AbstractInst):
                                                  output_paths=output_paths, run_number=run_details.run_number)
 
         return d_spacing_group, tof_group
+
+
+def _set_kwargs_from_basic_config_file(config_path, kwargs):
+    if config_path:
+        basic_config_dict = polaris_config_parser.get_basic_config(file_path=config_path)
+    else:
+        # Create an empty dictionary so we still get error checking below and nicer error messages
+        basic_config_dict = {}
+
+    # Set any unset properties:
+    key = "user_name"
+    _set_from_config_kwargs_helper(config_dictionary=basic_config_dict, kwargs=kwargs, key=key)
+    key = "calibration_directory"
+    _set_from_config_kwargs_helper(config_dictionary=basic_config_dict, kwargs=kwargs, key=key)
+    key = "output_directory"
+    _set_from_config_kwargs_helper(config_dictionary=basic_config_dict, kwargs=kwargs, key=key)
+    key = "apply_solid_angle"
+    _set_from_config_kwargs_helper(config_dictionary=basic_config_dict, kwargs=kwargs, key=key)
+
+
+def _set_from_config_kwargs_helper(config_dictionary, kwargs, key):
+    error_first = "Setting with name: '"
+    error_last = "' was not passed in the call or set in the basic config."
+    kwarg_value = kwargs.get(key, None)
+    if not kwarg_value:
+        # Only try to parse it if it wasn't passed
+        value = common.dictionary_key_helper(dictionary=config_dictionary, key=key, throws=True,
+                                             exception_msg=(error_first + key + error_last))
+        kwargs[key] = value
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/basic_config.yaml b/scripts/Diffraction/isis_powder/polaris_routines/basic_config.yaml
new file mode 100644
index 00000000000..fe8e8952517
--- /dev/null
+++ b/scripts/Diffraction/isis_powder/polaris_routines/basic_config.yaml
@@ -0,0 +1,9 @@
+# Basic setup
+
+user_name : "Mantid"
+apply_solid_angle : "True"
+
+calibration_directory : ""
+output_directory : ""
+
+advanced_config_file : "Not Set"
\ No newline at end of file
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py
index a62c54912f2..4649df2abda 100644
--- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py
@@ -1,7 +1,6 @@
 from __future__ import (absolute_import, division, print_function)
 
 import os
-
 import yaml
 
 import isis_powder.routines.common
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_calibration.yaml b/scripts/Diffraction/isis_powder/polaris_routines/polaris_calibration.yaml
index add54005ce5..4108aa2b9ba 100644
--- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_calibration.yaml
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_calibration.yaml
@@ -1,5 +1,6 @@
 
-# NOTE: All of the data below is TEST data - it is not representitive of any actual cycles/data values used
+# NOTE: All of the data below is TEST data - 
+# it is not representative of any actual cycles/data values used
 
 78334-82415:
   offset_file_name : "offsets_2011_cycle111b.cal"
@@ -24,7 +25,7 @@
     empty_run_numbers : "93106"
 
 
-95600-95614:
+95600-95614,97000:
   # Calibration run
   offset_file_name : "offsets_2011_cycle111b.cal"
   label : "16_4"
@@ -35,3 +36,13 @@
     vanadium_run_numbers : "95603-95607,95613-95614"
     empty_run_numbers : "78339"
 
+exceptions:
+  1234:
+    offset_file_name : "offsets_2011_cycle111b.cal"
+    label : "16_4"
+    chopper_on:
+      vanadium_run_numbers : "95603-95607,95613-95614"
+      empty_run_numbers : "78339"
+    chopper_off:
+      vanadium_run_numbers : "95603-95607,95613-95614"
+      empty_run_numbers : "78339"
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_config_parser.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_config_parser.py
new file mode 100644
index 00000000000..581151c8b58
--- /dev/null
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_config_parser.py
@@ -0,0 +1,24 @@
+from __future__ import (absolute_import, division, print_function)
+
+import yaml
+import os
+
+
+def get_basic_config(file_path):
+    # At the moment we just return it without additional processing
+    return _open_yaml_file(file_path=file_path)
+
+
+def _open_yaml_file(file_path):
+
+    if not os.path.isfile(file_path):
+        raise ValueError("File not found at: " + str(file_path))
+
+    read_config = None
+    with open(file_path, 'r') as yaml_stream:
+        try:
+            read_config = yaml.load(yaml_stream)
+        except yaml.YAMLError as exception:
+            raise ValueError("Failed to parse YAML. Exception was:\n" + str(exception))
+
+    return read_config
diff --git a/scripts/Diffraction/isis_powder/routines/common.py b/scripts/Diffraction/isis_powder/routines/common.py
index 063cd3ea893..3a76e6ed236 100644
--- a/scripts/Diffraction/isis_powder/routines/common.py
+++ b/scripts/Diffraction/isis_powder/routines/common.py
@@ -16,6 +16,20 @@ def create_calibration_by_names(calibration_runs, startup_objects, grouping_file
                            out_grouping_file_name=grouping_file_name, instrument=startup_objects)
 
 
+def dictionary_key_helper(dictionary, key, throws=True, exception_msg=None):
+    if key in dictionary:
+        return dictionary[key]
+    elif not throws:
+        return None
+    elif exception_msg:
+        # Print user specified message
+        raise KeyError(exception_msg)
+    else:
+        # Raise default python key error:
+        this_throws = dictionary[key]
+        return this_throws  # Never gets this far just makes linters happy
+
+
 def extract_bank_spectra(ws_to_split, num_banks):
     spectra_bank_list = []
     for i in range(0, num_banks):
@@ -51,10 +65,8 @@ def get_monitor_ws(ws_to_process, run_number_string, instrument):
 
 
 def load_current_normalised_ws(run_number_string, instrument):
-    read_in_ws = _load_raw_files(run_number_string=run_number_string, instrument=instrument)
-
     run_information = instrument.get_run_details(run_number=run_number_string)
-
+    read_in_ws = _load_raw_files(run_number_string=run_number_string, instrument=instrument)
     read_ws = instrument.normalise_ws(ws_to_correct=read_in_ws, run_details=run_information)
 
     output_name = "read_ws_output-" + str(g_ads_workaround["read_ws"])
-- 
GitLab