diff --git a/Framework/PythonInterface/plugins/algorithms/SaveGEMMAUDParamFile.py b/Framework/PythonInterface/plugins/algorithms/SaveGEMMAUDParamFile.py
new file mode 100644
index 0000000000000000000000000000000000000000..040f3bbf6a78f20c4df81bf44a1318f0a1fd4f00
--- /dev/null
+++ b/Framework/PythonInterface/plugins/algorithms/SaveGEMMAUDParamFile.py
@@ -0,0 +1,189 @@
+from __future__ import (absolute_import, division, print_function)
+
+import math
+import os
+import re
+
+from mantid.api import *
+from mantid.kernel import *
+
+
+class SaveGEMMAUDParamFile(PythonAlgorithm):
+
+    PROP_INPUT_WS = "InputWorkspace"
+    PROP_TEMPLATE_FILE = "TemplateFilename"
+    PROP_GSAS_PARAM_FILE = "GSASParamFile"
+    PROP_OUTPUT_FILE = "OutputFilename"
+
+    BANK_GROUPING = ([0] * 7) + ([1] * 8) + ([2] * 20) + ([3] * 42) + ([4] * 54) + ([5] * 35)
+    BANK_PARAMS_LINE = "^INS  [0-9]BNKPAR"
+    DIFFRACTOMETER_CONSTANTS_LINE = "^INS  [0-9] ICONS"
+    PROFILE_COEFFS_LINE_1 = "^INS  [0-9]PRCF 1"
+    PROFILE_COEFFS_LINE_2 = "^INS  [0-9]PRCF 2"
+
+    def category(self):
+        return "DataHandling\\Text;Diffraction\\DataHandling"
+
+    def name(self):
+        return "SaveGEMMAUDParamFile"
+
+    def summary(self):
+        return "Read calibration information from focused workspace and GSAS parameter file, and save to " \
+               "MAUD-readable calibration format"
+
+    def PyInit(self):
+        self.declareProperty(WorkspaceGroupProperty(name=self.PROP_INPUT_WS,
+                                                    defaultValue="",
+                                                    direction=Direction.Input),
+                             doc="WorkspaceGroup of focused banks")
+
+        self.declareProperty(FileProperty(name=self.PROP_GSAS_PARAM_FILE,
+                                          action=FileAction.Load,
+                                          defaultValue=""),
+                             doc="GSAS parameter file to read diffractometer constants and profile coefficients from")
+
+        self.declareProperty(FileProperty(name=self.PROP_TEMPLATE_FILE,
+                                          action=FileAction.Load,
+                                          defaultValue=self._find_isis_powder_dir()),
+                             doc="Template for the .maud file")
+
+        self.declareProperty(FileProperty(name=self.PROP_OUTPUT_FILE,
+                                          action=FileAction.Save,
+                                          defaultValue=""),
+                             doc="Name of the file to save to")
+
+    def PyExec(self):
+        input_ws = mtd[self.getPropertyValue(self.PROP_INPUT_WS)]
+        spectrum_numbers = [bank.getSpectrum(0).getSpectrumNo() for bank in input_ws]
+
+        gsas_filename = self.getProperty(self.PROP_GSAS_PARAM_FILE).value
+        distances, difas, difcs, tzeros, alpha_zeros, alpha_ones, beta_zeros, beta_ones, sigma_zeros, sigma_ones, \
+            sigma_twos = map(lambda param: self._expand_to_texture_bank(param, spectrum_numbers),
+                             self._parse_gsas_param_file(gsas_filename))
+
+        two_thetas, phis = zip(*[self._get_two_theta_and_phi(bank) for bank in input_ws])
+
+        with open(self.getProperty(self.PROP_TEMPLATE_FILE).value) as template_file:
+            template = template_file.read()
+
+        num_banks = input_ws.getNumberOfEntries()
+        with open(self.getProperty(self.PROP_OUTPUT_FILE).value, "w") as output_file:
+            ###### !!!!!trying with average bank DIFCS
+            average_difcs = [678, 664, 746, 872, 888, 761, 1425, 1405, 1391, 1389, 1390, 1396, 1433, 1426, 2411, 2399,
+                             2378, 2363, 2425, 2372, 2383, 2426, 2417, 2423, 3141, 3125, 3106, 3093, 3091, 3098, 3114,
+                             3160, 3143, 3161, 4219, 4222, 4239, 4211, 4221, 4204, 4206, 4210, 4207, 4242, 4242, 4229,
+                             4226, 4223, 4757, 4761, 4782, 4742, 4752, 4736, 4736, 4741, 4739, 4763, 4776, 4765, 4763,
+                             4761, 5274, 5279, 5302, 5257, 5267, 5251, 5249, 5255, 5254, 5271, 5289, 5278, 5278, 5277,
+                             6176, 6179, 6178, 6179, 6168, 6161, 6159, 6164, 6162, 6163, 6160, 6166, 6171, 6182, 6178,
+                             6172, 6178, 6181, 6661, 6663, 6663, 6661, 6654, 6648, 6647, 6651, 6649, 6651, 6647, 6651,
+                             6651, 6664, 6663, 6657, 6662, 6661, 7110, 7127, 7111, 7109, 7106, 7100, 7099, 7104, 7101,
+                             7104, 7100, 7101, 7101, 7112, 7112, 7107, 7112, 7110, 9001, 9002, 9005, 9031, 9129, 9109,
+                             9051, 9007, 9003, 9005, 9001, 9000, 9000, 9000, 9015, 9015, 9013, 9014, 9017, 9018, 9020,
+                             9013, 9012, 9013, 9048, 9143, 9228, 9171, 9271, 9053, 9057, 9119, 9045, 9047]
+
+            output_file.write(template.format(gsas_prm_file=gsas_filename,
+                                              inst_counter_bank="Bank1",
+                                              bank_ids="\n".join("Bank{}".format(i + 1) for i in range(num_banks)),
+                                              #difcs=self._format_param_list(difcs),
+                                              difas=self._format_param_list(average_difcs),
+                                              #difas=self._format_param_list(difas),
+                                              difcs=self._create_empty_param_list(num_banks),
+                                              #tzeros=self._format_param_list(tzeros),
+                                              tzeros=self._create_empty_param_list(num_banks),
+                                              thetas=self._format_param_list(two_thetas),
+                                              etas=self._format_param_list(phis),
+                                              dists=self._format_param_list(distances),
+                                              func_1_alpha_zeros=self._format_param_list(alpha_zeros),
+                                              func_1_alpha_ones=self._format_param_list(alpha_ones),
+                                              func_1_beta_zeros=self._format_param_list(beta_zeros),
+                                              func_1_beta_ones=self._format_param_list(beta_ones),
+                                              func_1_sigma_zeros=self._format_param_list(sigma_zeros),
+                                              func_1_sigma_ones=self._format_param_list(sigma_ones),
+                                              func_1_sigma_twos=self._format_param_list(sigma_twos),
+                                              func_2_alpha_zeros=self._create_empty_param_list(num_banks),
+                                              func_2_alpha_ones=self._create_empty_param_list(num_banks),
+                                              func_2_betas=self._create_empty_param_list(num_banks),
+                                              func_2_switches=self._create_empty_param_list(num_banks),
+                                              func_2_sigma_zeros=self._create_empty_param_list(num_banks),
+                                              func_2_sigma_ones=self._create_empty_param_list(num_banks),
+                                              func_2_sigma_twos=self._create_empty_param_list(num_banks),
+                                              func_2_gamma_zeros=self._create_empty_param_list(num_banks),
+                                              func_2_gamma_ones=self._create_empty_param_list(num_banks),
+                                              func_2_gamma_twos=self._create_empty_param_list(num_banks),
+                                              function_types=self._create_empty_param_list(num_banks, value="1")
+                                              ))
+
+    def _create_empty_param_list(self, num_banks, value="0"):
+        # Generate a list of zeroes, as several parameters are just zeroed in the .maud file
+        return "\n".join(value for _ in range(num_banks))
+
+    def _expand_to_texture_bank(self, bank_param_list, spectrum_numbers):
+        return (bank_param_list[self.BANK_GROUPING[spec_num]] for spec_num in spectrum_numbers)
+
+    def _find_isis_powder_dir(self):
+        script_dirs = config["pythonscripts.directories"].split(";")
+        diffraction_dir = None
+        for dir in script_dirs:
+            if "Diffraction" in dir:
+                diffraction_dir = dir
+
+        if diffraction_dir is None:
+            logger.warning("Could not find default diffraction directory for .maud template file: "
+                           "you'll have to find it yourself")
+            return ""
+        else:
+            return os.path.join(diffraction_dir, "isis_powder", "gem_routines", "maud_param_template.maud")
+
+    def _format_param_list(self, param_list):
+        return "\n".join(str(param) for param in param_list)
+
+    def _get_two_theta_and_phi(self, bank):
+        instrument = bank.getInstrument()
+        detector = bank.getDetector(0)
+
+        sample_pos = instrument.getSample().getPos()
+        source_pos = instrument.getSource().getPos()
+        det_pos = detector.getPos()
+
+        beam_dir = sample_pos - source_pos
+        detector_dir = det_pos - sample_pos
+
+        return math.degrees(beam_dir.angle(detector_dir)), math.degrees(detector.getPhi())
+
+    def _parse_gsas_param_file(self, gsas_filename):
+        with open(gsas_filename) as prm_file:
+            gsas_params_lines = prm_file.read().split("\n")
+
+        distances = []
+        difcs = []
+        difas = []
+        tzeros = []
+        alpha_zeros = []
+        alpha_ones = []
+        beta_zeros = []
+        beta_ones = []
+        sigma_zeros = []
+        sigma_ones = []
+        sigma_twos = []
+        for line in gsas_params_lines:
+            line_items = line.split()
+            if re.match(self.BANK_PARAMS_LINE, line):
+                distances.append(float(line_items[2]))
+            elif re.match(self.DIFFRACTOMETER_CONSTANTS_LINE, line):
+                difcs.append(float(line_items[3]))
+                difas.append(float(line_items[4]))
+                tzeros.append(float(line_items[5]))
+            elif re.match(self.PROFILE_COEFFS_LINE_1, line):
+                alpha_zeros.append(float(line_items[3]))
+                alpha_ones.append(float(line_items[4]))
+                beta_zeros.append(float(line_items[5]))
+                beta_ones.append(float(line_items[6]))
+            elif re.match(self.PROFILE_COEFFS_LINE_2, line):
+                sigma_zeros.append(float(line_items[3]))
+                sigma_ones.append(float(line_items[4]))
+                sigma_twos.append(float(line_items[5]))
+
+        return distances, difas, difcs, tzeros, alpha_zeros, alpha_ones, \
+            beta_zeros, beta_ones, sigma_zeros, sigma_ones, sigma_twos
+
+AlgorithmFactory.subscribe(SaveGEMMAUDParamFile)
diff --git a/scripts/Diffraction/isis_powder/gem_routines/maud_param_template.maud b/scripts/Diffraction/isis_powder/gem_routines/maud_param_template.maud
new file mode 100644
index 0000000000000000000000000000000000000000..078d06d56bd215aa9e52696d5384763f66fabd6f
--- /dev/null
+++ b/scripts/Diffraction/isis_powder/gem_routines/maud_param_template.maud
@@ -0,0 +1,202 @@
+data_instrument_GEM Diffractometer
+_diffrn_measurement_device_type 'GEM Diffractometer'
+_pd_proc_intensity_incident 2305.186(83.55167) #positive
+
+
+#subordinateObject_none cal
+
+_inst_intensity_calibration 'none cal'
+
+
+#end_subordinateObject_none cal
+
+
+#subordinateObject_IPNS/LANSCE Bank
+
+_inst_angular_calibration 'Multi Bank'
+
+_instrument_parameter_file {gsas_prm_file}
+_instrument_counter_bank {inst_counter_bank}
+_instrument_neutron_flight_path 9.07617
+
+loop_
+_instrument_counter_bank_ID
+{bank_ids}
+
+loop_
+_instrument_bank_difc
+{difcs}
+
+loop_
+_instrument_bank_difa
+{difas}
+
+loop_
+_instrument_bank_zero
+{tzeros}
+
+loop_
+_instrument_bank_tof_theta
+{thetas}
+
+loop_
+_instrument_bank_eta
+{etas}
+
+loop_
+_pd_instr_dist_spec/detc
+{dists}
+
+#end_subordinateObject_IPNS/LANSCE Bank
+
+
+#subordinateObject_IPNS/LANSCE TOF
+
+_pd_instr_geometry 'IPNS/LANSCE TOF'
+
+_diffrn_radiation_monochromator filtered
+_pd_instr_2theta_monochr_post 0
+_pd_instr_dist_src/samp 175.0
+_pd_instr_monochr_pre_spec filtered
+_pd_instr_2theta_monochr_pre 0
+_pd_instr_divg_ax_src/samp 0.0
+_pd_instr_divg_slit_auto false
+_diffrn_radiation_polarisn_norm 0
+_diffrn_radiation_polarisn_ratio 0
+
+#end_subordinateObject_IPNS/LANSCE TOF
+
+
+#subordinateObject_TOF
+
+_diffrn_measurement_method 'TOF'
+
+#end_subordinateObject_TOF
+
+
+#subordinateObject_TOF
+
+_diffrn_radiation_type 'TOF'
+
+#subordinateObject_Fake wavelength for TOF
+
+_diffrn_radiation_wavelength_id 'Fake wavelength for TOF'
+
+_diffrn_radiation_wavelength 0.0010
+_diffrn_radiation_wavelength_wt 1.0
+
+#end_subordinateObject_Fake wavelength for TOF
+
+#end_subordinateObject_TOF
+
+
+#subordinateObject_TOF
+
+_diffrn_radiation_detector 'TOF'
+
+_instrument_counter_bank_ID ?
+_diffrn_radiation_detector_theta 90.0
+_diffrn_radiation_detector_eta 0
+_diffrn_radiation_detector_efficiency 1.0
+_pd_instr_dist_spec/detc 1.0
+
+#end_subordinateObject_TOF
+
+
+#subordinateObject_GSAS TOF profile function
+
+_diffrn_inst_broadening 'GSAS TOF profile function'
+
+
+_instrument_parameter_file {gsas_prm_file}
+_instrument_counter_bank {inst_counter_bank}
+_riet_par_TOF_func_1_truncation_factor 0.01
+
+loop_
+_instrument_counter_bank_ID
+{bank_ids}
+
+loop_
+_riet_par_TOF_function_type
+{function_types}
+
+loop_
+_riet_par_TOF_func1_alpha0
+{func_1_alpha_zeros}
+
+loop_
+_riet_par_TOF_func1_alpha1
+{func_1_alpha_ones}
+
+loop_
+_riet_par_TOF_func1_beta0
+{func_1_beta_zeros}
+
+loop_
+_riet_par_TOF_func1_beta1
+{func_1_beta_ones}
+
+loop_
+_riet_par_TOF_func1_sigma0
+{func_1_sigma_zeros}
+
+loop_
+_riet_par_TOF_func1_sigma1
+{func_1_sigma_ones}
+
+loop_
+_riet_par_TOF_func1_sigma2
+{func_1_sigma_twos}
+
+loop_
+_riet_par_TOF_func2_alpha0
+{func_2_alpha_zeros}
+
+loop_
+_riet_par_TOF_func2_alpha1
+{func_2_alpha_ones}
+
+loop_
+_riet_par_TOF_func2_alpha1
+{func_2_alpha_ones}
+
+loop_
+_riet_par_TOF_func2_beta
+{func_2_betas}
+
+loop_
+_riet_par_TOF_func2_switch
+{func_2_switches}
+
+loop_
+_riet_par_TOF_func2_sigma0
+{func_2_sigma_zeros}
+
+loop_
+_riet_par_TOF_func2_sigma1
+{func_2_sigma_ones}
+
+loop_
+_riet_par_TOF_func2_sigma2
+{func_2_sigma_twos}
+
+loop_
+_riet_par_TOF_func2_gamma0
+{func_2_gamma_zeros}
+
+loop_
+_riet_par_TOF_func2_gamma1
+{func_2_gamma_ones}
+
+loop_
+_riet_par_TOF_func2_gamma2
+{func_2_gamma_twos}
+
+#end_subordinateObject_GSAS TOF profile function
+
+
+#subordinateObject_none abs
+
+_exptl_absorpt_correction_type 'none abs'
+
+#end_subordinateObject_none abs