diff --git a/docs/source/api/python/techniques/ISISPowder-Pearl-v1.rst b/docs/source/api/python/techniques/ISISPowder-Pearl-v1.rst
index e16e3b43226ea22170e9729a4c78d026f789615e..f87c4126a0bd570dd885e9e246d6f30345175526 100644
--- a/docs/source/api/python/techniques/ISISPowder-Pearl-v1.rst
+++ b/docs/source/api/python/techniques/ISISPowder-Pearl-v1.rst
@@ -44,7 +44,7 @@ File structure:
     label : "10_1"
     vanadium_run_numbers : "123-125"
     empty_run_numbers : "135-137"
-    calibration_file : "offsets_example_10_1.cal"
+    offset_file_name : "offsets_example_10_1.cal"
 
   141-145: ...etc.
 
diff --git a/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py b/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py
index b372b05df7140d3442aa137d61b494761c632774..b398c8df5890d6779f03969ce60b71df0705ca77 100644
--- a/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py
+++ b/scripts/Diffraction/isis_powder/gem_routines/gem_algs.py
@@ -1,9 +1,9 @@
 from __future__ import (absolute_import, division, print_function)
 
-import os
 import mantid.simpleapi as mantid
 
-from isis_powder.routines import absorb_corrections, common, RunDetails, yaml_parser
+from isis_powder.routines import absorb_corrections, common
+from isis_powder.routines.RunDetails import create_run_details_object, RunDetailsFuncWrapper, WrappedFunctionsRunDetails
 from isis_powder.gem_routines import gem_advanced_config
 
 
@@ -17,42 +17,28 @@ def calculate_absorb_corrections(ws_to_correct, multiple_scattering):
     return ws_to_correct
 
 
-def get_run_details(run_number_string, inst_settings):
-    run_number = common.get_first_run_number(run_number_string=run_number_string)
-
-    # Get calibration mapping file
-    cycle_map = yaml_parser.get_run_dictionary(run_number_string=run_number_string,
-                                               file_path=inst_settings.cal_mapping_path)
-
-    label = common.cal_map_dictionary_key_helper(cycle_map, "label")
-    offset_file_name = common.cal_map_dictionary_key_helper(cycle_map, "offset_file_name")
-
-    chopper_dict = common.cal_map_dictionary_key_helper(cycle_map, inst_settings.mode)
+def gem_get_chopper_config(forwarded_value, inst_settings):
+    # Forwarded value should be a cal mapping
+    cal_mapping = forwarded_value
+    return common.cal_map_dictionary_key_helper(cal_mapping, inst_settings.mode)
 
-    empty_runs = common.cal_map_dictionary_key_helper(chopper_dict, "empty_run_numbers")
-    vanadium_runs = common.cal_map_dictionary_key_helper(chopper_dict, "vanadium_run_numbers")
 
-    # For GEM the grouping and offset file are identical
-    calibration_folder = os.path.normpath(os.path.expanduser(inst_settings.calibration_dir))
-    grouping_file_path = os.path.join(calibration_folder, inst_settings.grouping_file_name)
-
-    splined_vanadium_name = common.generate_splined_name(vanadium_runs, offset_file_name)
-
-    label_calibration_folder = os.path.join(calibration_folder, label)
-    offset_file_path = os.path.join(label_calibration_folder, offset_file_name)
-    splined_file_path = os.path.join(label_calibration_folder, splined_vanadium_name)
+def get_run_details(run_number_string, inst_settings):
+    cal_mapping_callable = RunDetailsFuncWrapper().add_to_func_chain(
+        WrappedFunctionsRunDetails.get_cal_mapping_dict, run_number_string=run_number_string,
+        inst_settings=inst_settings
+    ).add_to_func_chain(function=gem_get_chopper_config, inst_settings=inst_settings)
 
-    run_details = RunDetails.RunDetails(run_number=run_number)
-    run_details.empty_runs = empty_runs
-    # Rarely used attribute so we will leave it as optional
-    run_details.sample_empty = inst_settings.sample_empty if hasattr(inst_settings, "sample_empty") else None
-    run_details.output_run_string = run_number_string
-    run_details.label = label
-    run_details.vanadium_run_numbers = vanadium_runs
+    # Get empty and vanadium
+    err_message = "this must be under the relevant Rietveld or PDF mode."
 
-    run_details.grouping_file_path = grouping_file_path
-    run_details.offset_file_path = offset_file_path
+    empty_run_callable = cal_mapping_callable.add_to_func_chain(
+        function=WrappedFunctionsRunDetails.cal_dictionary_key_helper, key="empty_run_numbers",
+        append_to_error_message=err_message)
 
-    run_details.splined_vanadium_file_path = splined_file_path
+    vanadium_run_callable = cal_mapping_callable.add_to_func_chain(
+        function=WrappedFunctionsRunDetails.cal_dictionary_key_helper, key="vanadium_run_numbers",
+        append_to_error_message=err_message)
 
-    return run_details
+    return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings,
+                                     empty_run_call=empty_run_callable, vanadium_run_call=vanadium_run_callable)
diff --git a/scripts/Diffraction/isis_powder/gem_routines/gem_param_mapping.py b/scripts/Diffraction/isis_powder/gem_routines/gem_param_mapping.py
index 2ba72497b9c7292e2dbcf259d2685af50ad27438..86d4c97290498058017210e215311984ab6da98f 100644
--- a/scripts/Diffraction/isis_powder/gem_routines/gem_param_mapping.py
+++ b/scripts/Diffraction/isis_powder/gem_routines/gem_param_mapping.py
@@ -14,12 +14,12 @@ attr_mapping = \
      ParamMapEntry(ext_name="focused_cropping_values",   int_name="focused_cropping_values"),
      ParamMapEntry(ext_name="grouping_file_name",        int_name="grouping_file_name"),
      ParamMapEntry(ext_name="input_mode",                int_name="input_batching", enum_class=INPUT_BATCHING),
-     ParamMapEntry(ext_name="mode",                      int_name="mode", enum_class=GEM_CHOPPER_MODES),
+     ParamMapEntry(ext_name="mode",                      int_name="mode",           enum_class=GEM_CHOPPER_MODES),
      ParamMapEntry(ext_name="multiple_scattering",       int_name="multiple_scattering"),
      ParamMapEntry(ext_name="raw_tof_cropping_values",   int_name="raw_tof_cropping_values"),
      ParamMapEntry(ext_name="run_in_range",              int_name="run_in_range"),
      ParamMapEntry(ext_name="run_number",                int_name="run_number"),
-     ParamMapEntry(ext_name="sample_empty",              int_name="sample_empty", optional=True),
+     ParamMapEntry(ext_name="sample_empty",              int_name="sample_empty",   optional=True),
      ParamMapEntry(ext_name="spline_coefficient",        int_name="spline_coeff"),
      ParamMapEntry(ext_name="output_directory",          int_name="output_dir"),
      ParamMapEntry(ext_name="unit_to_keep",              int_name="unit_to_keep",
diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py
index 5d0e4cea4d5327123d9c4520eec7fc925558b946..7f2adb19ce52b4465d27c226d93cce04e8b124e6 100644
--- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py
+++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py
@@ -4,8 +4,7 @@ import numpy as numpy
 import mantid.simpleapi as mantid
 
 import isis_powder.routines.common as common
-from isis_powder.routines import yaml_parser
-from isis_powder.routines.RunDetails import RunDetails
+from isis_powder.routines.RunDetails import create_run_details_object, RunDetailsFuncWrapper, WrappedFunctionsRunDetails
 
 
 def attenuate_workspace(attenuation_file_path, ws_to_correct):
@@ -70,45 +69,28 @@ def generate_vanadium_absorb_corrections(van_ws):
 
 
 def get_run_details(run_number_string, inst_settings):
-    first_run_number = common.get_first_run_number(run_number_string=run_number_string)
-    mapping_dict = yaml_parser.get_run_dictionary(run_number_string=first_run_number,
-                                                  file_path=inst_settings.cal_map_path)
-
-    calibration_file_name = common.cal_map_dictionary_key_helper(mapping_dict, "calibration_file")
-    empty_run_numbers = common.cal_map_dictionary_key_helper(mapping_dict, "empty_run_numbers")
-    label = common.cal_map_dictionary_key_helper(mapping_dict, "label")
-    vanadium_run_numbers = common.cal_map_dictionary_key_helper(mapping_dict, "vanadium_run_numbers")
-
-    # Use generate out name to provide the unique fingerprint for this file
-    splined_vanadium_name = common.generate_splined_name(
-        generate_out_name(run_number_string=vanadium_run_numbers,
-                          absorb_on=inst_settings.absorb_corrections,
-                          long_mode_on=inst_settings.long_mode, tt_mode=inst_settings.tt_mode))
-
-    calibration_dir = inst_settings.calibration_dir
-    cycle_calibration_dir = os.path.join(calibration_dir, label)
-
-    absorption_file_path = os.path.join(calibration_dir, inst_settings.van_absorb_file)
-    calibration_file_path = os.path.join(cycle_calibration_dir, calibration_file_name)
+    splined_name_list = ["_tt-" + inst_settings.tt_mode]
+    if inst_settings.absorb_corrections:
+        splined_name_list.append("_abs")
+    if inst_settings.long_mode:
+        splined_name_list.append("_long")
+
+    grouping_file_name_callable = RunDetailsFuncWrapper().add_to_func_chain(function=_pearl_get_tt_grouping_file_name,
+                                                                            inst_settings=inst_settings)
+
+    return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings,
+                                     grouping_file_name_call=grouping_file_name_callable,
+                                     splined_name_list=splined_name_list,
+                                     van_abs_file_name=inst_settings.van_absorb_file)
+
+
+def _pearl_get_tt_grouping_file_name(inst_settings):
     tt_grouping_key = str(inst_settings.tt_mode).lower() + '_grouping'
     try:
-        grouping_file_path = os.path.join(calibration_dir, getattr(inst_settings, tt_grouping_key))
+        grouping_file_name = getattr(inst_settings, tt_grouping_key)
     except AttributeError:
         raise ValueError("The tt_mode: " + str(inst_settings.tt_mode).lower() + " is unknown")
-
-    splined_vanadium_path = os.path.join(cycle_calibration_dir, splined_vanadium_name)
-
-    run_details = RunDetails(run_number=first_run_number)
-    run_details.output_run_string = run_number_string
-    run_details.offset_file_path = calibration_file_path
-    run_details.grouping_file_path = grouping_file_path
-    run_details.empty_runs = empty_run_numbers
-    run_details.label = label
-    run_details.splined_vanadium_file_path = splined_vanadium_path
-    run_details.vanadium_absorption_path = absorption_file_path
-    run_details.vanadium_run_numbers = vanadium_run_numbers
-
-    return run_details
+    return grouping_file_name
 
 
 def normalise_ws_current(ws_to_correct, monitor_ws, spline_coeff, lambda_values, integration_range):
diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py
index 8f12c7a7924fe5f8a97b07f7137f133792762b2e..b437e99a6c2c5b5fca9fb03253d32d7af8f779e2 100644
--- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py
+++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_param_mapping.py
@@ -8,10 +8,10 @@ attr_mapping = \
     [
         ParamMapEntry(ext_name="attenuation_file_path",      int_name="attenuation_file_path"),
         ParamMapEntry(ext_name="config_file",                int_name="config_file_name"),
-        ParamMapEntry(ext_name="calibration_config_path",    int_name="cal_map_path"),
+        ParamMapEntry(ext_name="calibration_config_path",    int_name="cal_mapping_path"),
         ParamMapEntry(ext_name="calibration_directory",      int_name="calibration_dir"),
         ParamMapEntry(ext_name="do_absorb_corrections",      int_name="absorb_corrections"),
-        ParamMapEntry(ext_name="focus_mode", int_name="focus_mode", enum_class=PEARL_FOCUS_MODES),
+        ParamMapEntry(ext_name="focus_mode",                 int_name="focus_mode", enum_class=PEARL_FOCUS_MODES),
         ParamMapEntry(ext_name="long_mode",                  int_name="long_mode"),
         ParamMapEntry(ext_name="monitor_lambda_crop_range",  int_name="monitor_lambda"),
         ParamMapEntry(ext_name="monitor_integration_range",  int_name="monitor_integration_range"),
@@ -27,7 +27,7 @@ attr_mapping = \
         ParamMapEntry(ext_name="tt88_grouping",              int_name="tt88_grouping"),
         ParamMapEntry(ext_name="tt70_grouping",              int_name="tt70_grouping"),
         ParamMapEntry(ext_name="tt35_grouping",              int_name="tt35_grouping"),
-        ParamMapEntry(ext_name="tt_mode", int_name="tt_mode", enum_class=PEARL_TT_MODES),
+        ParamMapEntry(ext_name="tt_mode",                    int_name="tt_mode", enum_class=PEARL_TT_MODES),
         ParamMapEntry(ext_name="user_name",                  int_name="user_name"),
         ParamMapEntry(ext_name="vanadium_absorb_file",       int_name="van_absorb_file"),
         ParamMapEntry(ext_name="vanadium_tof_cropping",      int_name="van_tof_cropping"),
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py
index e8bedd0bcee4d16d50027e58deb169951c901929..5d7329fd67eebec2d65a924cb65bdc67c5abafb7 100644
--- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py
@@ -1,10 +1,9 @@
 from __future__ import (absolute_import, division, print_function)
 
 import mantid.simpleapi as mantid
-import os
 
 from isis_powder.routines import absorb_corrections, common
-from isis_powder.routines.RunDetails import RunDetailsFuncWrapper, get_cal_mapping, cal_map_dictionary_key_helper_wrapper
+from isis_powder.routines.RunDetails import create_run_details_object, RunDetailsFuncWrapper, WrappedFunctionsRunDetails
 from isis_powder.polaris_routines import polaris_advanced_config
 
 
@@ -17,7 +16,32 @@ def calculate_absorb_corrections(ws_to_correct, multiple_scattering):
     return ws_to_correct
 
 
-def get_chopper_config(forwarded_value, inst_settings):
+def get_run_details(run_number_string, inst_settings):
+    # Get the chopper mode as vanadium and empty run numbers depend on different modes
+    chopper_config_callable = RunDetailsFuncWrapper().\
+        add_to_func_chain(function=WrappedFunctionsRunDetails.get_cal_mapping_dict, run_number_string=run_number_string,
+                          inst_settings=inst_settings).\
+        add_to_func_chain(function=polaris_get_chopper_config, inst_settings=inst_settings)
+
+    # Then use the results to set the empty and vanadium runs
+    err_message = "this must be under the relevant chopper_on / chopper_off section."
+
+    empty_runs_callable = chopper_config_callable.add_to_func_chain(
+        WrappedFunctionsRunDetails.cal_dictionary_key_helper,
+        key="empty_run_numbers", append_to_error_message=err_message)
+
+    vanadium_runs_callable = chopper_config_callable.add_to_func_chain(
+        WrappedFunctionsRunDetails.cal_dictionary_key_helper, key="vanadium_run_numbers",
+        append_to_error_message=err_message)
+
+    run_details = create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings,
+                                            empty_run_call=empty_runs_callable,
+                                            vanadium_run_call=vanadium_runs_callable)
+
+    return run_details
+
+
+def polaris_get_chopper_config(forwarded_value, inst_settings):
     # The previous result is a cal_mapping
     cal_mapping = forwarded_value
 
@@ -29,47 +53,6 @@ def get_chopper_config(forwarded_value, inst_settings):
     return chopper_config
 
 
-def get_run_details(run_number_string, inst_settings):
-    # Forward result from get_cal_mapping to get_chopper_config
-    chopper_config_callable = RunDetailsFuncWrapper().\
-        add_to_func_chain(function=get_cal_mapping, run_number_string=run_number_string, inst_settings=inst_settings).\
-        add_to_func_chain(function=get_chopper_config, inst_settings=inst_settings)
-
-    err_message = "This must be under the relevant chopper_on / chopper_off section."
-    empty_runs_callable = chopper_config_callable.add_to_func_chain(cal_map_dictionary_key_helper_wrapper,
-                                                                    "empty_run_numbers", err_message)
-
-    vanadium_runs_callable = chopper_config_callable.add_to_func_chain(cal_map_dictionary_key_helper_wrapper,
-                                                                       "vanadium_run_numbers", err_message)
-
-    empty_runs = empty_runs_callable.get_result()
-    van_runs = vanadium_runs_callable.get_result()
-
-    grouping_full_path = os.path.normpath(os.path.expanduser(inst_settings.calibration_dir))
-    grouping_full_path = os.path.join(grouping_full_path, inst_settings.grouping_file_name)
-
-    #in_calib_dir = os.path.join(inst_settings.calibration_dir, label)
-    #offsets_file_full_path = os.path.join(in_calib_dir, offset_file_name)
-#
-    ## Generate the name of the splined file we will either be loading or saving
-    #chopper_status = "ChopperOn" if inst_settings.chopper_on else "ChopperOff"
-    #splined_vanadium_name = common.generate_splined_name(vanadium_runs, chopper_status, offset_file_name)
-#
-    #splined_vanadium = os.path.join(in_calib_dir, splined_vanadium_name)
-#
-    #run_details = RunDetails(run_number=run_number)
-    #run_details.output_run_string = run_number_string
-    #run_details.empty_runs = empty_runs
-    #run_details.vanadium_run_numbers = vanadium_runs
-    #run_details.label = label
-#
-    #run_details.offset_file_path = offsets_file_full_path
-    #run_details.grouping_file_path = grouping_full_path
-    #run_details.splined_vanadium_file_path = splined_vanadium
-#
-    #return run_details
-
-
 def process_vanadium_for_focusing(bank_spectra, mask_path, spline_number):
     bragg_masking_list = _read_masking_file(mask_path)
     masked_workspace_list = _apply_bragg_peaks_masking(bank_spectra, mask_list=bragg_masking_list)
diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py
index e5634b076f621807c7a69fe02a2c58c55d0d1dca..57a8976aca489f0fc252c6a7fdb95439c54deed7 100644
--- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py
+++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_param_mapping.py
@@ -7,7 +7,7 @@ from isis_powder.routines.common_enums import INPUT_BATCHING
 attr_mapping = \
     [
      ParamMapEntry(ext_name="calibration_directory",    int_name="calibration_dir"),
-     ParamMapEntry(ext_name="calibration_mapping_file", int_name="cal_mapping_file"),
+     ParamMapEntry(ext_name="calibration_mapping_file", int_name="cal_mapping_path"),
      ParamMapEntry(ext_name="chopper_on",               int_name="chopper_on"),
      ParamMapEntry(ext_name="config_file",              int_name="config_file"),
      ParamMapEntry(ext_name="do_absorb_corrections",    int_name="do_absorb_corrections"),
diff --git a/scripts/Diffraction/isis_powder/routines/RunDetails.py b/scripts/Diffraction/isis_powder/routines/RunDetails.py
index c3256eda4b80209be3eaac650386df5f48427ec2..03617eee6195f6e3716a77dc8891ffdebb8ffc86 100644
--- a/scripts/Diffraction/isis_powder/routines/RunDetails.py
+++ b/scripts/Diffraction/isis_powder/routines/RunDetails.py
@@ -1,33 +1,103 @@
 from __future__ import (absolute_import, division, print_function)
 
 from isis_powder.routines import common, yaml_parser
+import os
 
 
-def create_run_details_object(run_number_string, inst_settings):
-    pass
-
-
-def get_cal_mapping(run_number_string, inst_settings):
-    # Get the python dictionary from the YAML mapping
+def create_run_details_object(run_number_string, inst_settings, empty_run_call=None,
+                              grouping_file_name_call=None, vanadium_run_call=None,
+                              splined_name_list=None, van_abs_file_name=None):
+    cal_map_dict = WrappedFunctionsRunDetails.get_cal_mapping_dict(
+        run_number_string=run_number_string, inst_settings=inst_settings)
     run_number = common.get_first_run_number(run_number_string=run_number_string)
-    cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number,
-                                                      file_path=inst_settings.cal_mapping_file)
-
-    return cal_mapping_dict
-
-
-def cal_map_dictionary_key_helper_wrapper(*args, **kwargs):
-    forwarded_value = kwargs.pop("forwarded_value")
-    return common.cal_map_dictionary_key_helper(forwarded_value, *args, **kwargs)
+    calibration_dir = os.path.normpath(os.path.expanduser(inst_settings.calibration_dir))
+
+    # Get names of files we will be using
+    label = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="label")
+    offset_file_name = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="offset_file_name")
+
+    # Sample empty if there is one
+    sample_empty = inst_settings.sample_empty if hasattr(inst_settings, "sample_empty") else None
+
+    # Always make sure the offset file name is included
+    if splined_name_list:
+        splined_name_list.append(offset_file_name)
+    else:
+        splined_name_list = [offset_file_name]
+
+    # These can either be generic or custom so defer to another method
+    results_dict = _get_customisable_attributes(
+        cal_dict=cal_map_dict, inst_settings=inst_settings, empty_run_call=empty_run_call,
+        grouping_name_call=grouping_file_name_call, vanadium_run_call=vanadium_run_call,
+        splined_name_list=splined_name_list)
+
+    # Generate the paths
+    grouping_file_path = os.path.join(calibration_dir, results_dict["grouping_file_name"])
+    # Offset  and splined vanadium is within the correct label folder
+    offset_file_path = os.path.join(calibration_dir, label, offset_file_name)
+    splined_van_path = os.path.join(calibration_dir, label, results_dict["splined_van_name"])
+    van_absorb_path = os.path.join(calibration_dir, van_abs_file_name) if van_abs_file_name else None
+
+    output_run_string = run_number_string
+
+    return _RunDetails(empty_run_number=results_dict["empty_runs"], run_number=run_number,
+                       output_run_string=output_run_string, label=label, offset_file_path=offset_file_path,
+                       grouping_file_path=grouping_file_path, splined_vanadium_path=splined_van_path,
+                       vanadium_run_number=results_dict["vanadium_runs"], sample_empty=sample_empty,
+                       vanadium_abs_path=van_absorb_path)
+
+
+def _get_customisable_attributes(cal_dict, inst_settings, empty_run_call, grouping_name_call, vanadium_run_call,
+                                 splined_name_list):
+    dict_to_return = {}
+    if empty_run_call:
+        empty_runs = empty_run_call.get_result()
+    else:
+        empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_dict, key="empty_run_numbers")
+    dict_to_return["empty_runs"] = empty_runs
+
+    if vanadium_run_call:
+        vanadium_runs = vanadium_run_call.get_result()
+    else:
+        vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_dict, key="vanadium_run_numbers")
+    dict_to_return["vanadium_runs"] = vanadium_runs
+
+    if grouping_name_call:
+        grouping_name = grouping_name_call.get_result()
+    else:
+        grouping_name = inst_settings.grouping_file_name
+    dict_to_return["grouping_file_name"] = grouping_name
+
+    dict_to_return["splined_van_name"] = common.generate_splined_name(vanadium_runs, append_list=splined_name_list)
+
+    return dict_to_return
+
+
+class WrappedFunctionsRunDetails(object):
+    def __init__(self):
+        pass
+
+    @staticmethod
+    def get_cal_mapping_dict(run_number_string, inst_settings):
+        # Get the python dictionary from the YAML mapping
+        run_number = common.get_first_run_number(run_number_string=run_number_string)
+        cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number,
+                                                          file_path=inst_settings.cal_mapping_path)
+        return cal_mapping_dict
+
+    @staticmethod
+    def cal_dictionary_key_helper(key, append_to_error_message=None, **kwargs):
+        forwarded_value = kwargs.pop("forwarded_value")
+        return common.cal_map_dictionary_key_helper(dictionary=forwarded_value, key=key,
+                                                    append_to_error_message=append_to_error_message)
 
 
 class RunDetailsFuncWrapper(object):
     # Holds a callable method, associated args and return value so we can pass it in
     # as a single method
 
-    def __init__(self, function=None, func_args=None, func_kwargs=None):
+    def __init__(self, function=None, func_kwargs=None):
         self.function = function
-        self.function_args = func_args
         self.function_kwargs = func_kwargs
 
         self._previous_callable = None
@@ -43,9 +113,9 @@ class RunDetailsFuncWrapper(object):
 
         if forwarded_value:
             self.function_kwargs["forwarded_value"] = forwarded_value
-            self._returned_value = self.function(*self.function_args, **self.function_kwargs)
+            self._returned_value = self.function(**self.function_kwargs)
         else:
-            self._returned_value = self.function(*self.function_args, **self.function_kwargs)
+            self._returned_value = self.function(**self.function_kwargs)
 
         self._function_is_executed = True
 
@@ -53,13 +123,16 @@ class RunDetailsFuncWrapper(object):
         if not previous_callable:
             return None
         elif not isinstance(previous_callable, RunDetailsFuncWrapper):
-            raise ValueError("previous callable is not a RunDetailsFuncWrapper type")
+            raise ValueError("Previous callable is not a RunDetailsFuncWrapper type")
 
         self._previous_callable = previous_callable
 
-    def add_to_func_chain(self, function, *args, **kwargs):
+    def add_to_func_chain(self, function, *args, **func_kwargs):
+        if args:
+            # If we allow args with position Python gets confused as the forwarded value can be in the first place too
+            raise RuntimeError("Cannot use un-named arguments with callable methods")
         # Construct a new object that will be the next in line
-        next_in_chain = RunDetailsFuncWrapper(function=function, func_args=args, func_kwargs=kwargs)
+        next_in_chain = RunDetailsFuncWrapper(function=function, func_kwargs=func_kwargs)
         next_in_chain._set_previous_callable(self)
         return next_in_chain
 
@@ -69,14 +142,14 @@ class RunDetailsFuncWrapper(object):
         return self._returned_value
 
 
-class RunDetails(object):
+class _RunDetails(object):
     """
     This class holds the full file paths associated with each run and various other useful attributes
     """
 
     def __init__(self, empty_run_number, run_number, output_run_string, label,
                  offset_file_path, grouping_file_path, splined_vanadium_path, vanadium_run_number,
-                 sample_empty=None, vanadium_abs_path=None):
+                 sample_empty, vanadium_abs_path):
         # Essential attribute
         self.empty_runs = empty_run_number
         self.run_number = run_number
diff --git a/scripts/Diffraction/isis_powder/routines/common.py b/scripts/Diffraction/isis_powder/routines/common.py
index b91da6e3b312392bca91a874b1db515391684172..d4e05a7e8da543ce753241e12b8f0817be0481a9 100644
--- a/scripts/Diffraction/isis_powder/routines/common.py
+++ b/scripts/Diffraction/isis_powder/routines/common.py
@@ -143,19 +143,24 @@ def generate_run_numbers(run_number_string):
     return run_list
 
 
-def generate_splined_name(vanadium_string, *args):
+def generate_splined_name(vanadium_string, append_list=None, *args):
     """
     Generates a unique splined vanadium name which encapsulates
     any properties passed into this method so that the vanadium
     can be later loaded.
     :param vanadium_string: The name of this vanadium run
     :param args: Any identifying properties to append to the name
+    :param append_list: The args can also be passed as a list of values to append
     :return: The splined vanadium name
     """
     out_name = "VanSplined" + '_' + str(vanadium_string)
     for value in args:
         out_name += '_' + str(value)
 
+    if append_list:
+        for value in append_list:
+            out_name += '_' + str(value)
+
     out_name += ".nxs"
     return out_name