extracts all the relevant information from script_information and returns it as individual variables
        Args:
            script_information: information of the script. This can be
                - a dictionary
                - a Script instance
                - name of Script class
            package (optional): name of the package to which the script belongs, i.e. pylabcontrol or b26toolkit.
                                Only used when script_information is a string
        Returns:
            module, script_class_name, script_settings, script_instruments, script_sub_scripts, script_info, package

def get_script_information(script_information, package='pylabcontrol', verbose=False):
        """
        extracts all the relevant information from script_information and returns it as individual variables
        Args:
            script_information: information of the script. This can be
                - a dictionary
                - a Script instance
                - name of Script class
            package (optional): name of the package to which the script belongs, i.e. pylabcontrol or b26toolkit.
                                Only used when script_information is a string
        Returns:
            module, script_class_name, script_settings, script_instruments, script_sub_scripts, script_info, package
        """

        script_settings = None
        script_instruments = None
        script_sub_scripts = None
        script_class_name = None
        module = None  # this is the module that contains the script where we look for scripts
        script_info = None # this is the docstring that describes the script
        module_path = package + '.scripts'
        script_filepath = None
        module_file = None

        if isinstance(script_information, dict):
            if 'settings' in script_information:
                script_settings = script_information['settings']
            if 'filepath' in script_information:
                script_filepath = str(script_information['filepath'])
                module_path, module_file = module_name_from_path(script_filepath, verbose = False)
            if 'package' in script_information:
                package = script_information['package']
            else:
                assert 'filepath' in script_information  # there should be a filepath if we load form a b26 file
                # in the case that we generate the script_information from a .py file the package is given by the name of the highest module
                if 'filepath' in script_information:
                    package = module_path.split('.')[0]

            script_class_name = str(script_information['class'])
            if 'ScriptIterator' in script_class_name:
                module_path = package + '.core.script_iterator'
            if 'instruments' in script_information:
                script_instruments = script_information['instruments']
            if 'scripts' in script_information:
                script_sub_scripts = script_information['scripts']
            if 'info' in script_information:
                script_info = script_information['info']
                
        elif isinstance(script_information, str):
            script_class_name = script_information


        elif issubclass(script_information, Script):
            # watch out when testing this code from __main__, then classes might not be identified correctly because the path is different
            # to avoid this problem call from pylabcontrol.core import Script (otherwise the path to Script is __main__.Script)
            script_class_name = script_information.__name__
            package = script_information.__module__.split('.')[0]
            module_path = script_information.__module__

        assert isinstance(package, str)


        # if the script has not been created yet, i.e. script_class_name: ScriptIteratorB26 or ScriptIterator
        if verbose:
            print(('script_filepath', script_filepath))
            print(('path_to_module', module_path))

        if script_filepath is not None:
            # scriptiterator loaded from file
            if os.path.basename(script_filepath.split('.pyc')[0].split('.py')[0]) == 'script_iterator':
                module_path = package + '.core.script_iterator'

        # if the script has been created already, i.e. script_class_name: package.dynamic_script_iterator
        # todo: now there is the prefix package
        if len(script_class_name.split('dynamic_script_iterator')) == 2 and \
                script_class_name.split('dynamic_script_iterator')[1].isdigit():
            # package = 'pylabcontrol' # all the dynamic iterator scripts are defined in the name space of pylabcontrol
            # all the dynamic iterator scripts are defined in the name space of package.pylabcontrol.core.script_iterator
            # module = import_module(package + '.pylabcontrol.core.script_iterator')
            module_path = package

        # the package should be the highest level of the module path
        # assert module_path.split('.')[0] == package
        # assert isinstance(module_path, str)  # in that case we should have defined a module_path to load the module
        # assert module is None  # we haven't loaded the module yet

        # try:
        #     print(module_path)
        #     module = import_module(module_path)
        #     print(module)
        # except ImportError:
        #     pass
        # print('module', module_path)

        #appends path to this module to the python path if it is not present so it can be used
        if module_file and (module_file not in sys.path):
            sys.path.append(module_file)

        module = import_module(module_path)
        # check if module was found!
        if module is None or not hasattr(module, script_class_name):
            # import sys
            print('here is the pythonpath')
            for path in sys.path:
                print(path)
            import time
            time.sleep(1)
            print(('Could not find the module that contains ' + script_class_name + ' in module ' + module_path))
            raise ImportError('Could not find the module that contains ' + script_class_name + ' in module ' + module_path)

        # if the module has a name of type dynamic_script_iteratorX where X is a number the module is script iterator
        return module, script_class_name, script_settings, script_instruments, script_sub_scripts, script_info, package