コード例 #1
0
def get_parameter_value(nxsfile, plugin_name, plugin_param):
    content = Content()
    content.fopen(nxsfile)
    plist = content.plugin_list.plugin_list

    for plugin in plist:
        if plugin['name'] == plugin_name:
            if plugin_param in plugin['data'].keys():
                print plugin_name, plugin['data'][plugin_param]
コード例 #2
0
ファイル: utils.py プロジェクト: yousefmoazzam/hebi
def create_process_list_from_user_data(data):
    """
    Creates a process list from user supplied data.
    """
    process_list = Content()

    # For each plugin
    for i, pl in enumerate(data['plugins']):
        pos = str(i + 1)

        # Add plugin
        process_list.add(pl['name'], pos)

        # Set plugin enable state
        process_list.on_and_off(
            pos,
            const.PLUGIN_ENABLED if pl['active'] else const.PLUGIN_DISABLED)

        # Set parameter values
        for param in pl['parameters']:
            if param['name'] == 'preview':
                # Don't cast a preview value, since it always comes into
                # flask as a string and should always be cast to a string, but
                # sometimes it can have a value of '[]' which gets cast to the
                # empty list by Content.value() and plugin.utils._dumps()
                cast_param_val = param['value']
            else:
                cast_param_val = process_list.value(param['value'])

            process_list.modify(pos, param['name'], cast_param_val, ref=True)

    return process_list
コード例 #3
0
    def setUp(self):
        self.test_folder = tempfile.mkdtemp(suffix='template_test/')
        self.tif_folder = os.path.join(self.test_folder, 'tiffs/')
        os.mkdir(self.tif_folder)

        # copy across the process list to the working directory
        self.process_list_path = os.path.join(self.test_folder,
                                              'xrd_template_test.nxs')
        shutil.copyfile(tu.get_test_process_path('xrd_template_test.nxs'),
                        self.process_list_path)

        utils.populate_plugins()
        self.process_list = Content()
        self.process_list.fopen(self.process_list_path, update=False)
        for idx in self.process_list.get_positions():
            self.process_list.refresh(idx)
        self.detX_axis_label = {
            'dim': '$idx_detx',
            'name': 'detector_x',
            'value': None,
            'units': 'pixels'
        }
        self.detY_axis_label = {
            'dim': '$idx_dety',
            'name': 'detector_y',
            'value': None,
            'units': 'pixels'
        }

        self.yaml = OrderedDict()
        # now make some standard modifications
        self.yaml['inherit'] = [
            tu.get_test_data_path(
                os.path.join('i18_templates', 'xrd_calibration.yml'))
        ]
        self.yaml['xrd'] = OrderedDict()
        self.yaml['xrd']['params'] = {}
        self.yaml['xrd']['data'] = {}
        self.yaml['xrd']['data']['folder'] = self.tif_folder
        self.yaml['xrd']['params']['cfile'] = \
            "$h5py.File('%s', 'r')" % tu.get_test_data_path('LaB6_calibration_new.nxs')

        self.yaml['xrd']['patterns'] = {}
        self.yaml['xrd']['patterns']['DIFFRACTION'] = {
            'core_dims':
            '$(idx_detx, idx_dety)',
            'slice_dims':
            '$tuple([d for d in dims if d not in [idx_detx, idx_dety]])'
        }
        self.yaml['xrd']['axis_labels'] = {}
        self.yaml['xrd']['metadata'] = {}
        self.data_file_path = 'test_data.nxs'
        self.data_file = h5.File(self.data_file_path,
                                 'w')  # this will have the axes in.
コード例 #4
0
 def save_yaml_and_change_process_list(self):
     self.yml_path = os.path.join(self.test_folder, 'xrd_tiff.yml')
     with open(self.yml_path, 'w') as f:
         yu.dump_yaml(self.yaml, f)
     # now set the template path in the process list
     # uses the parameter name instead of number
     # because the number can change between runs
     self.process_list = Content()
     self.process_list.fopen(self.process_list_path, update=False)
     self.process_list.modify('1', 'yaml_file', self.yml_path)
     self.process_list.save(self.process_list_path)
コード例 #5
0
def get_parameter_value(nxsfile, plugin_name, plugin_param):
    content = Content()
    content.fopen(nxsfile)
    plist = content.plugin_list.plugin_list

    found_params = []
    for plugin in plist:
        if plugin['name'] == plugin_name:
            if plugin_param in list(plugin['data'].keys()):
                found_params.append(plugin['data'][plugin_param])

    return found_params
コード例 #6
0
 def _refresh_process_file(self, path):
     content = Content()
     # open
     content.fopen(path, update=True)
     # refresh
     positions = content.get_positions()
     for pos_str in positions:
         content.refresh(pos_str)
     # save
     content.save(content.filename)
コード例 #7
0
    def setUp(self):
        self.test_folder = tempfile.mkdtemp(suffix='template_test/')
        self.tif_folder = os.path.join(self.test_folder, 'tiffs/')
        os.mkdir(self.tif_folder)

        # copy across the process list to the working directory
        self.process_list_path = os.path.join(self.test_folder, 'xrd_template_test.nxs')
        shutil.copyfile(tu.get_test_process_path('xrd_template_test.nxs'),
                        self.process_list_path)

        utils.populate_plugins()
        self.process_list = Content()
        self.process_list.fopen(self.process_list_path, update=False)
        for idx in self.process_list.get_positions():
            self.process_list.refresh(idx)
        self.detX_axis_label = {'dim': '$idx_detx', 'name': 'detector_x', 'value': None, 'units': 'pixels'}
        self.detY_axis_label = {'dim': '$idx_dety', 'name': 'detector_y', 'value': None, 'units': 'pixels'}

        self.yaml = OrderedDict()
        # now make some standard modifications
        self.yaml['inherit'] = [tu.get_test_data_path(os.path.join('i18_templates', 'xrd_calibration.yml'))]
        self.yaml['xrd'] = OrderedDict()
        self.yaml['xrd']['params'] = {}
        self.yaml['xrd']['data'] = {}
        self.yaml['xrd']['data']['folder'] = self.tif_folder
        self.yaml['xrd']['params']['cfile'] = \
            "$h5py.File('%s', 'r')" % tu.get_test_data_path('LaB6_calibration_new.nxs')

        self.yaml['xrd']['patterns'] = {}
        self.yaml['xrd']['patterns']['DIFFRACTION'] = {'core_dims': '$(idx_detx, idx_dety)',
                                                       'slice_dims': '$tuple([d for d in dims if d not in [idx_detx, idx_dety]])'}
        self.yaml['xrd']['axis_labels'] = {}
        self.yaml['xrd']['metadata'] = {}
        self.data_file_path = 'test_data.nxs'
        self.data_file = h5.File(self.data_file_path, 'w')  # this will have the axes in.
コード例 #8
0
 def _refresh_process_file(self, path):
     content = Content()
     # open
     content.fopen(path, update=True)
     # refresh
     positions = content.get_positions()
     for pos_str in positions:
         content.refresh(pos_str)
     # save
     content.save(content.filename)
コード例 #9
0
ファイル: server.py プロジェクト: yousefmoazzam/hebi
def process_list_info():
    """
    Return the contents of a specific process list

    .. :quickref: ProcessList; Get the contents of a process list
    :query string filename: the absolute path to a process list file on the filesystem
    """
    fname = const.ROOT_MOUNT_POINT + request.args.get(const.KEY_FILENAME)

    # Ensure file is a valid process list
    file_validation = validate_file(fname, is_file_a_process_list)
    if not file_validation['is_valid']:
        abort(404, file_validation['error_message'])

    # Open process list
    process_list = Content()
    process_list.fopen(fname)

    # Refresh all plugins in the process list once it has been opened
    positions = process_list.get_positions()
    for pos_str in positions:
        process_list.refresh(pos_str)

    # Format plugin list
    plugins = [plugin_list_entry_to_dict(p) for \
               p in process_list.plugin_list.plugin_list]

    data = {const.KEY_FILENAME: fname, const.KEY_PLUGINS: plugins}

    validation.process_list_list_filename_schema(data)
    return jsonify(data)
コード例 #10
0
ファイル: __init__.py プロジェクト: dtasev/hebi
    def process_list_list():
        # Listing process list files in a given search directory
        if urlparams.KEY_PATH in request.args:
            # Get the absolute path being searched
            user_path = request.args.get(urlparams.KEY_PATH)
            abs_path = os.path.abspath(os.path.expanduser(user_path))

            data = {
                urlparams.KEY_PATH:
                abs_path,
                urlparams.KEY_FILES:
                list(find_files_recursive(abs_path, is_file_a_process_list)),
            }

            validation.filename_listing_schema(data)
            return jsonify(data)

        # Listing details of a specific process list
        elif urlparams.KEY_FILENAME in request.args:
            fname = request.args.get(urlparams.KEY_FILENAME)

            # Ensure file is a valid process list
            if not validate_file(fname, is_file_a_process_list):
                abort(status.HTTP_404_NOT_FOUND)

            # Open process list
            process_list = Content()
            process_list.fopen(fname)

            # Format plugin list
            plugins = [plugin_list_entry_to_dict(p) for \
                       p in process_list.plugin_list.plugin_list]

            data = {
                urlparams.KEY_FILENAME: fname,
                urlparams.KEY_PLUGINS: plugins
            }

            validation.process_list_list_filename_schema(data)
            return jsonify(data)

        else:
            abort(status.HTTP_400_BAD_REQUEST)
コード例 #11
0
ファイル: server.py プロジェクト: yousefmoazzam/hebi
def add_plugin_to_process_list(plugin_name, plugin_index):
    """
    Add a plugin to the current process list, and return a dict representation
    of the newly added plugin

    .. :quickref: Plugin; Add plugin to process list
    :param string plugin_name: the name of the plugin to add
    :param int plugin_index: the index in the current process list to add the
        plugin to
    """

    if plugin_name not in pu.plugins:
        abort(status.HTTP_404_NOT_FOUND)

    # create a process list with a single plugin in it (an instance of the
    # plugin desired to be added to the process list editor) so then plugin
    # data of the desired format can be passed to plugin_list_entry_to_dict()
    process_list = Content()
    dummy_pos = "1"
    process_list.add(plugin_name, dummy_pos)
    process_list.on_and_off(dummy_pos, const.PLUGIN_ENABLED)
    plugin = process_list.plugin_list.plugin_list[0]
    data = plugin_list_entry_to_dict(plugin)
    # update with the desired pos value
    data['pos'] = plugin_index
    validation.process_list_entry_schema(data)
    return jsonify(data)
コード例 #12
0
ファイル: server.py プロジェクト: DiamondLightSource/hebi
def process_list_list():
    # Listing process list files in a given search directory
    if const.KEY_PATH in request.args:
        # Get the absolute path being searched
        user_path = request.args.get(const.KEY_PATH)
        abs_path = os.path.abspath(os.path.expanduser(user_path))

        data = {
            const.KEY_PATH: abs_path,
            const.KEY_FILES: list(
                find_files_recursive(abs_path, is_file_a_process_list)),
        }

        validation.filename_listing_schema(data)
        return jsonify(data)

    # Listing details of a specific process list
    elif const.KEY_FILENAME in request.args:
        fname = const.ROOT_MOUNT_POINT + request.args.get(const.KEY_FILENAME)

        # Ensure file is a valid process list
        if not validate_file(fname, is_file_a_process_list):
            abort(status.HTTP_404_NOT_FOUND)

        # Open process list
        process_list = Content()
        process_list.fopen(fname)

        # Refresh all plugins in the process list once it has been opened
        positions = process_list.get_positions()
        for pos_str in positions:
            process_list.refresh(pos_str)

        # Format plugin list
        plugins = [plugin_list_entry_to_dict(p) for \
                   p in process_list.plugin_list.plugin_list]

        data = {
            const.KEY_FILENAME: fname,
            const.KEY_PLUGINS: plugins
        }

        validation.process_list_list_filename_schema(data)
        return jsonify(data)

    else:
        abort(status.HTTP_400_BAD_REQUEST)
コード例 #13
0
def create_process_list_from_user_data(data):
    """
    Creates a process list from user supplied data.
    """
    process_list = Content()

    # For each plugin
    for i, pl in enumerate(data['plugins']):
        pos = str(i + 1)

        # Add plugin
        process_list.add(pl['name'], pos)

        # Set plugin enable state
        process_list.on_and_off(
            pos,
            const.PLUGIN_ENABLED if pl['active'] else const.PLUGIN_DISABLED)

        # Set parameter values
        for param in pl['parameters']:
            cast_param_val = process_list.value(param['value'])
            process_list.modify(pos, param['name'], cast_param_val, ref=True)

    return process_list
コード例 #14
0
ファイル: server.py プロジェクト: DiamondLightSource/hebi
def add_plugin_to_process_list():
    request_data = request.get_json()

    if request_data['pluginName'] not in pu.plugins:
        abort(status.HTTP_404_NOT_FOUND)

    # create a process list with a single plugin in it (an instance of the
    # plugin desired to be added to the process list editor) so then plugin
    # data of the desired format can be passed to plugin_list_entry_to_dict()
    process_list = Content()
    dummy_pos = "1"
    process_list.add(request_data['pluginName'], dummy_pos)
    process_list.on_and_off(dummy_pos, const.PLUGIN_ENABLED)
    plugin = process_list.plugin_list.plugin_list[0]
    data = plugin_list_entry_to_dict(plugin)
    # update with the desired pos value
    data['pos'] = request_data['pluginIndex']
    validation.process_list_entry_schema(data)
    return jsonify(data)
コード例 #15
0
class TemplateLoaderTest(unittest.TestCase):
    def test_1D_data(self):
        A = 11

        X = 10
        Y = 13

        expected_output_shape = (A, X, Y)
        expected_top_corners = np.arange(A, dtype=np.float32)

        self.create_N_tiffs(A, frame_size=(X, Y))
        # create a data file with the axis information
        self.data_file['entry/A'] = np.arange(A)
        self.data_file.close()

        # edit and save the yaml
        self.yaml['xrd']['data']['shape'] = '$(len(A_vals),)'
        self.yaml['xrd']['params'].update({
            'idx_A': 0,
            'idx_detx': 1,
            'idx_dety': 2,
            'A_vals': "$dfile['entry/A'].value",
            'dims': "$range(0, 3)"
        })

        # add some axis labels
        self.yaml['xrd']['axis_labels'] = {
            0: {
                'dim': '$idx_A',
                'name': 'A',
                'value': '$A_vals',
                'units': 'pixels'
            },
            1: self.detX_axis_label,
            2: self.detY_axis_label
        }

        self.save_yaml_and_change_process_list()

        run_protected_plugin_runner(
            tu.set_options(self.data_file_path,
                           process_file=self.process_list_path,
                           out_path=self.test_folder))

        # now check the result

        result = h5.File(os.path.join(self.test_folder, 'test_processed.nxs'),
                         'r')['entry/final_result_xrd/data']
        np.testing.assert_array_equal(
            result.shape,
            expected_output_shape,
            err_msg='The output shape is not as expected.')
        result_corners = result[..., -1, -1]
        np.testing.assert_equal(
            result_corners.dtype,
            expected_top_corners.dtype,
            err_msg='The array does not output the correct type.')
        np.testing.assert_array_equal(
            result_corners,
            expected_top_corners,
            err_msg="The output values are not as expected")

    def test_2D_data(self):
        A = 3
        B = 4

        X = 10
        Y = 13

        expected_output_shape = (A, B, X, Y)
        expected_top_corners = np.arange(A * B, dtype=np.float32).reshape(
            (A, B))

        self.create_N_tiffs(A * B, frame_size=(X, Y))
        # create a data file with the axis information
        self.data_file['entry/A'] = np.arange(A)
        self.data_file['entry/B'] = np.arange(B)
        self.data_file.close()

        # edit and save the yaml
        self.yaml['xrd']['data']['shape'] = '$(len(A_vals), len(B_vals))'
        self.yaml['xrd']['params'].update({
            'idx_A': 0,
            'idx_B': 1,
            'idx_detx': 2,
            'idx_dety': 3,
            'A_vals': "$dfile['entry/A'].value",
            'B_vals': "$dfile['entry/B'].value",
            'dims': "$range(0, 4)"
        })

        self.yaml['xrd']['axis_labels'] = {
            0: {
                'dim': '$idx_A',
                'name': 'A',
                'value': '$A_vals',
                'units': 'pixels'
            },
            1: {
                'dim': '$idx_B',
                'name': 'B',
                'value': '$B_vals',
                'units': 'pixels'
            },
            2: self.detX_axis_label,
            3: self.detY_axis_label
        }

        self.save_yaml_and_change_process_list()

        run_protected_plugin_runner(
            tu.set_options(self.data_file_path,
                           process_file=self.process_list_path,
                           out_path=self.test_folder))

        result = h5.File(os.path.join(self.test_folder, 'test_processed.nxs'),
                         'r')['entry/final_result_xrd/data']
        np.testing.assert_array_equal(
            result.shape,
            expected_output_shape,
            err_msg='The output shape is not as expected.')
        result_corners = result[..., -1, -1]
        np.testing.assert_equal(
            result_corners.dtype,
            expected_top_corners.dtype,
            err_msg='The array does not output the correct type.')
        np.testing.assert_array_equal(
            result_corners,
            expected_top_corners,
            err_msg="The output values are not as expected")

    def test_3D_data(self):
        A = 3
        B = 4
        C = 5

        X = 10
        Y = 13
        expected_output_shape = (A, B, C, X, Y)
        expected_top_corners = np.arange(A * B * C, dtype=np.float32).reshape(
            (A, B, C))

        self.create_N_tiffs(A * B * C, frame_size=(X, Y))
        # create a data file with the axis information
        self.data_file['entry/A'] = np.arange(A)
        self.data_file['entry/B'] = np.arange(B)
        self.data_file['entry/C'] = np.arange(C)
        self.data_file.close()

        # edit and save the yaml
        self.yaml['xrd']['data'][
            'shape'] = '$(len(A_vals), len(B_vals), len(C_vals))'
        self.yaml['xrd']['params'].update({
            'idx_A': 0,
            'idx_B': 1,
            'idx_C': 2,
            'idx_detx': 3,
            'idx_dety': 4,
            'A_vals': "$dfile['entry/A'].value",
            'B_vals': "$dfile['entry/B'].value",
            'C_vals': "$dfile['entry/C'].value",
            'dims': "$range(0, 4)"
        })

        self.yaml['xrd']['axis_labels'] = {
            0: {
                'dim': '$idx_A',
                'name': 'A',
                'value': '$A_vals',
                'units': 'pixels'
            },
            1: {
                'dim': '$idx_B',
                'name': 'B',
                'value': '$B_vals',
                'units': 'pixels'
            },
            2: {
                'dim': '$idx_C',
                'name': 'C',
                'value': '$C_vals',
                'units': 'pixels'
            },
            3: self.detX_axis_label,
            4: self.detY_axis_label
        }

        self.save_yaml_and_change_process_list()

        run_protected_plugin_runner(
            tu.set_options(self.data_file_path,
                           process_file=self.process_list_path,
                           out_path=self.test_folder))

        result = h5.File(os.path.join(self.test_folder, 'test_processed.nxs'),
                         'r')['entry/final_result_xrd/data']
        np.testing.assert_array_equal(
            result.shape,
            expected_output_shape,
            err_msg='The output shape is not as expected.')
        result_corners = result[..., -1, -1]
        np.testing.assert_equal(
            result_corners.dtype,
            expected_top_corners.dtype,
            err_msg='The array does not output the correct type.')
        np.testing.assert_array_equal(
            result_corners,
            expected_top_corners,
            err_msg="The output values are not as expected")

    def setUp(self):
        self.test_folder = tempfile.mkdtemp(suffix='template_test/')
        self.tif_folder = os.path.join(self.test_folder, 'tiffs/')
        os.mkdir(self.tif_folder)

        # copy across the process list to the working directory
        self.process_list_path = os.path.join(self.test_folder,
                                              'xrd_template_test.nxs')
        shutil.copyfile(tu.get_test_process_path('xrd_template_test.nxs'),
                        self.process_list_path)

        utils.populate_plugins()
        self.process_list = Content()
        self.process_list.fopen(self.process_list_path, update=False)
        for idx in self.process_list.get_positions():
            self.process_list.refresh(idx)
        self.detX_axis_label = {
            'dim': '$idx_detx',
            'name': 'detector_x',
            'value': None,
            'units': 'pixels'
        }
        self.detY_axis_label = {
            'dim': '$idx_dety',
            'name': 'detector_y',
            'value': None,
            'units': 'pixels'
        }

        self.yaml = OrderedDict()
        # now make some standard modifications
        self.yaml['inherit'] = [
            tu.get_test_data_path(
                os.path.join('i18_templates', 'xrd_calibration.yml'))
        ]
        self.yaml['xrd'] = OrderedDict()
        self.yaml['xrd']['params'] = {}
        self.yaml['xrd']['data'] = {}
        self.yaml['xrd']['data']['folder'] = self.tif_folder
        self.yaml['xrd']['params']['cfile'] = \
            "$h5py.File('%s', 'r')" % tu.get_test_data_path('LaB6_calibration_new.nxs')

        self.yaml['xrd']['patterns'] = {}
        self.yaml['xrd']['patterns']['DIFFRACTION'] = {
            'core_dims':
            '$(idx_detx, idx_dety)',
            'slice_dims':
            '$tuple([d for d in dims if d not in [idx_detx, idx_dety]])'
        }
        self.yaml['xrd']['axis_labels'] = {}
        self.yaml['xrd']['metadata'] = {}
        self.data_file_path = 'test_data.nxs'
        self.data_file = h5.File(self.data_file_path,
                                 'w')  # this will have the axes in.

    def tearDown(self):
        shutil.rmtree(self.test_folder)

    def create_N_tiffs(self, N, file_pattern='%04d.tif', frame_size=(10, 13)):
        '''
        Creates a stack of N tiffs with given frame_size and file pattern in self.tif_folder.
        :param N: The number of tiffs in the stack
        :param file_pattern: The printf pattern for the file names.
        :param frame_size: The shape of the frames. Default: (10,13).
        '''

        data = np.ones(frame_size, dtype=np.float)
        for idx in range(N):
            file_path = os.path.join(self.tif_folder, (file_pattern % idx))
            tifffile.imsave(file_path, data * idx)

    def save_yaml_and_change_process_list(self):
        yml_path = os.path.join(self.test_folder, 'xrd_tiff.yml')
        with open(yml_path, 'w') as f:
            yu.dump_yaml(self.yaml, f)
        # now set the template path in the process list
        self.process_list.modify('1', '2', yml_path)
        self.process_list.save(self.process_list_path)
コード例 #16
0
class TemplateLoaderTest(unittest.TestCase):

    def test_1D_data(self):
        A = 11

        X = 10
        Y = 13

        expected_output_shape = (A, X, Y)
        expected_top_corners = np.arange(A, dtype=np.float32)

        self.create_N_tiffs(A, frame_size=(X, Y))
        # create a data file with the axis information
        self.data_file['entry/A'] = np.arange(A)
        self.data_file.close()

        # edit and save the yaml
        self.yaml['xrd']['data']['shape'] = '$(len(A_vals),)'
        self.yaml['xrd']['params'].update({'idx_A': 0,
                                           'idx_detx': 1,
                                           'idx_dety': 2,
                                           'A_vals': "$dfile['entry/A'].value",
                                           'dims': "$range(0, 3)"})

        # add some axis labels
        self.yaml['xrd']['axis_labels'] = {0: {'dim': '$idx_A', 'name': 'A', 'value': '$A_vals', 'units': 'pixels'},
                                           1: self.detX_axis_label,
                                           2: self.detY_axis_label}

        self.save_yaml_and_change_process_list()

        run_protected_plugin_runner(tu.set_options(self.data_file_path,
                                                   process_file=self.process_list_path,
                                                   out_path=self.test_folder))

        # now check the result

        result = h5.File(os.path.join(self.test_folder, 'test_processed.nxs'), 'r')['entry/final_result_xrd/data']
        np.testing.assert_array_equal(result.shape, expected_output_shape,
                                      err_msg='The output shape is not as expected.')
        result_corners = result[..., -1, -1]
        np.testing.assert_equal(result_corners.dtype, expected_top_corners.dtype,
                                err_msg='The array does not output the correct type.')
        np.testing.assert_array_equal(result_corners, expected_top_corners,
                                      err_msg="The output values are not as expected")


    def test_2D_data(self):
        A = 3
        B = 4

        X = 10
        Y = 13

        expected_output_shape = (A, B, X, Y)
        expected_top_corners = np.arange(A*B, dtype=np.float32).reshape((A, B))

        self.create_N_tiffs(A*B, frame_size=(X, Y))
        # create a data file with the axis information
        self.data_file['entry/A'] = np.arange(A)
        self.data_file['entry/B'] = np.arange(B)
        self.data_file.close()

        # edit and save the yaml
        self.yaml['xrd']['data']['shape'] = '$(len(A_vals), len(B_vals))'
        self.yaml['xrd']['params'].update({'idx_A': 0,
                                           'idx_B': 1,
                                           'idx_detx': 2,
                                           'idx_dety': 3,
                                           'A_vals': "$dfile['entry/A'].value",
                                           'B_vals': "$dfile['entry/B'].value",
                                           'dims': "$range(0, 4)"})

        self.yaml['xrd']['axis_labels'] = {0: {'dim': '$idx_A', 'name': 'A', 'value': '$A_vals', 'units': 'pixels'},
                                           1: {'dim': '$idx_B', 'name': 'B', 'value': '$B_vals', 'units': 'pixels'},
                                           2: self.detX_axis_label,
                                           3: self.detY_axis_label}

        self.save_yaml_and_change_process_list()

        run_protected_plugin_runner(tu.set_options(self.data_file_path,
                                                   process_file=self.process_list_path,
                                                   out_path=self.test_folder))

        result = h5.File(os.path.join(self.test_folder, 'test_processed.nxs'), 'r')['entry/final_result_xrd/data']
        np.testing.assert_array_equal(result.shape, expected_output_shape,
                                      err_msg='The output shape is not as expected.')
        result_corners = result[..., -1, -1]
        np.testing.assert_equal(result_corners.dtype, expected_top_corners.dtype,
                                err_msg='The array does not output the correct type.')
        np.testing.assert_array_equal(result_corners, expected_top_corners,
                                      err_msg="The output values are not as expected")

    def test_3D_data(self):
        A = 3
        B = 4
        C = 5

        X = 10
        Y = 13
        expected_output_shape = (A, B, C, X, Y)
        expected_top_corners = np.arange(A*B*C, dtype=np.float32).reshape((A, B, C))

        self.create_N_tiffs(A*B*C, frame_size=(X, Y))
        # create a data file with the axis information
        self.data_file['entry/A'] = np.arange(A)
        self.data_file['entry/B'] = np.arange(B)
        self.data_file['entry/C'] = np.arange(C)
        self.data_file.close()

        # edit and save the yaml
        self.yaml['xrd']['data']['shape'] = '$(len(A_vals), len(B_vals), len(C_vals))'
        self.yaml['xrd']['params'].update({'idx_A': 0,
                                           'idx_B': 1,
                                           'idx_C': 2,
                                           'idx_detx': 3,
                                           'idx_dety': 4,
                                           'A_vals': "$dfile['entry/A'].value",
                                           'B_vals': "$dfile['entry/B'].value",
                                           'C_vals': "$dfile['entry/C'].value",
                                           'dims': "$range(0, 4)"})

        self.yaml['xrd']['axis_labels'] = {0: {'dim': '$idx_A', 'name': 'A', 'value': '$A_vals', 'units': 'pixels'},
                                           1: {'dim': '$idx_B', 'name': 'B', 'value': '$B_vals', 'units': 'pixels'},
                                           2: {'dim': '$idx_C', 'name': 'C', 'value': '$C_vals', 'units': 'pixels'},
                                           3: self.detX_axis_label,
                                           4: self.detY_axis_label}

        self.save_yaml_and_change_process_list()

        run_protected_plugin_runner(tu.set_options(self.data_file_path,
                                                   process_file=self.process_list_path,
                                                   out_path=self.test_folder))

        result = h5.File(os.path.join(self.test_folder, 'test_processed.nxs'), 'r')['entry/final_result_xrd/data']
        np.testing.assert_array_equal(result.shape, expected_output_shape,
                                      err_msg='The output shape is not as expected.')
        result_corners = result[..., -1, -1]
        np.testing.assert_equal(result_corners.dtype, expected_top_corners.dtype,
                                err_msg='The array does not output the correct type.')
        np.testing.assert_array_equal(result_corners, expected_top_corners,
                                      err_msg="The output values are not as expected")

    def setUp(self):
        self.test_folder = tempfile.mkdtemp(suffix='template_test/')
        self.tif_folder = os.path.join(self.test_folder, 'tiffs/')
        os.mkdir(self.tif_folder)

        # copy across the process list to the working directory
        self.process_list_path = os.path.join(self.test_folder, 'xrd_template_test.nxs')
        shutil.copyfile(tu.get_test_process_path('xrd_template_test.nxs'),
                        self.process_list_path)

        utils.populate_plugins()
        self.process_list = Content()
        self.process_list.fopen(self.process_list_path, update=False)
        for idx in self.process_list.get_positions():
            self.process_list.refresh(idx)
        self.detX_axis_label = {'dim': '$idx_detx', 'name': 'detector_x', 'value': None, 'units': 'pixels'}
        self.detY_axis_label = {'dim': '$idx_dety', 'name': 'detector_y', 'value': None, 'units': 'pixels'}

        self.yaml = OrderedDict()
        # now make some standard modifications
        self.yaml['inherit'] = [tu.get_test_data_path(os.path.join('i18_templates', 'xrd_calibration.yml'))]
        self.yaml['xrd'] = OrderedDict()
        self.yaml['xrd']['params'] = {}
        self.yaml['xrd']['data'] = {}
        self.yaml['xrd']['data']['folder'] = self.tif_folder
        self.yaml['xrd']['params']['cfile'] = \
            "$h5py.File('%s', 'r')" % tu.get_test_data_path('LaB6_calibration_new.nxs')

        self.yaml['xrd']['patterns'] = {}
        self.yaml['xrd']['patterns']['DIFFRACTION'] = {'core_dims': '$(idx_detx, idx_dety)',
                                                       'slice_dims': '$tuple([d for d in dims if d not in [idx_detx, idx_dety]])'}
        self.yaml['xrd']['axis_labels'] = {}
        self.yaml['xrd']['metadata'] = {}
        self.data_file_path = 'test_data.nxs'
        self.data_file = h5.File(self.data_file_path, 'w')  # this will have the axes in.


    def tearDown(self):
        shutil.rmtree(self.test_folder)

    def create_N_tiffs(self, N, file_pattern='%04d.tif', frame_size=(10, 13)):
        '''
        Creates a stack of N tiffs with given frame_size and file pattern in self.tif_folder.
        :param N: The number of tiffs in the stack
        :param file_pattern: The printf pattern for the file names.
        :param frame_size: The shape of the frames. Default: (10,13).
        '''

        data = np.ones(frame_size, dtype=np.float)
        for idx in range(N):
            file_path = os.path.join(self.tif_folder, (file_pattern % idx))
            tifffile.imsave(file_path, data*idx)

    def save_yaml_and_change_process_list(self):
        yml_path = os.path.join(self.test_folder, 'xrd_tiff.yml')
        with open(yml_path, 'w') as f:
            yu.dump_yaml(self.yaml, f)
        # now set the template path in the process list
        self.process_list.modify('1', '2', yml_path)
        self.process_list.save(self.process_list_path)