Ejemplo n.º 1
0
    def __init__(self, init_dict={}):
        """
        Create a new organism from a dictary of parameters. The dictionary
        is specified in blossom.default_fields.
        """
        # Set up defaults based on organism parameters
        for (field, default) in default_fields.organism_fields.items():
            setattr(self, field, init_dict.get(field, default))

        # Set up custom fields provided in initialization dictionary
        init_keys = set(init_dict.keys())
        default_keys = set(default_fields.organism_fields.keys())
        for custom_field in (init_keys - default_keys):
            setattr(self, custom_field, init_dict[custom_field])

        # Set unique id for organism
        if self.organism_id is None:
            # self.organism_id = str(uuid.uuid4())
            self.organism_id = self.get_new_id()

        # Set current water level for uninitialized organism
        if self.drinking_type is not None and self.water_current is None:
            self.water_current = self.water_initial

        # Set current food level for uninitialized organism
        if self.eating_type is not None and self.food_current is None:
            self.food_current = self.food_initial

        # Import custom modules / paths
        if self.custom_module_fns is not None:
            self._custom_modules = []
            for i, path in enumerate(cast_to_list(self.custom_module_fns)):
                temp_module = imp.load_source('%s' % i, path)
                self._custom_modules.append(temp_module)
Ejemplo n.º 2
0
def request_translation(translator, sentences, source_language,
                        target_language):
    """
    Request a MachineTranslator to perform a translation. The request process is implemented
    based on the type of MachineTranslator. For example, a SERVERLAND type uses a MT Server Land
    to request a translation.
    Preconditions:
        translator:    A MachineTranslator object.
        sentences:     A list of strings.
    Exceptions:
        UnsupportedLanguagePair:The target translator doesn't support the language pair.
        UndefinedTranslator:    When looking up the ServerlandHost for a MachineTranslator, if none exists (this should not happen).
        ServerlandConfigError:  The ServerlandHost has an error.
    """

    # Make sure that the translator supports the language pair
    if not translator.is_language_pair_supported(source_language,
                                                 target_language):
        raise UnsupportedLanguagePair(translator, source_language,
                                      target_language)

    # Generate a request id
    request_id = utils.generate_request_id()

    # Make sure that sentences is a list.
    sentences = utils.cast_to_list(sentences)
    #    if not isinstance(sentences, list):
    #        print "Retrieved only one sentence."
    #        sentences = [sentences]

    # One sentence per line, to make it easier for the translator to do its job.
    text = "\n".join(sentence for sentence in sentences)

    # Determine the machine translator type.
    if translator.type == SERVERLAND:
        # Get the ServerlandHost
        try:
            # TODO: Change this host reference. Currently, only one ServerLand host is allowed.
            serverland_host = translator.serverlandhost_set.all()[0]
        except IndexError:
            raise UndefinedTranslator(translator)

        source_file_id = "%s-%s-%s" % (request_id, source_language.code,
                                       target_language.code)

        try:
            #            print "Requesting the translation"
            #            print serverland_host.token, request_id, translator.shortname
            #            print utils.get_iso639_2(source_language.code), utils.get_iso639_2(target_language.code)
            #            print source_file_id
            #            print text

            # Request the translation.
            proxy = xmlrpclib.ServerProxy(serverland_host.url)
            result = proxy.create_translation(
                serverland_host.token,  # Authentication token
                request_id,  # Custom request ID
                translator.shortname,  # MT ServerLand worker
                utils.get_iso639_2(source_language.code
                                   ),  # Source language (in bibliographic)
                utils.get_iso639_2(target_language.code
                                   ),  # Target language (in bibliographic)
                source_file_id,  # Composite id
                text)  # Sentence(s) to translate

            # TODO: For now, just print the results.
            print result

            # TODO: Return the request_id
            return request_id
        except xmlrpclib.Fault as ex:
            raise ServerlandConfigError(serverland_host, ex)
Ejemplo n.º 3
0
    def fetch_translations(self):
        proxy = xmlrpclib.ServerProxy(self.url)

        # Fetch the translation requests (and make sure the result is a list)
        requests = utils.cast_to_list(proxy.list_requests(self.token))

        # Retrieve the translation requests that are "ready"
        completedRequests = [
            request for request in requests if request['ready']
        ]

        # Process the completed requests
        for completedRequest in completedRequests:
            # Get the result
            result = proxy.list_results(self.token,
                                        completedRequest['request_id'])

            # Get the external request id and sentences
            external_request_id = completedRequest['shortname']
            result_sentences = utils.clean_string(
                result['result'].strip()).split('\n')

            # FIXME: Add exception handling when the translation request is not found.
            try:
                # Look up the original translation request
                request = TranslationRequest.objects.get_by_external_id(
                    external_request_id)

                # TODO: Should we delete the translations, or filter them some way in Serverland to prevent re-retrieving translations? This could get expensive...
                if requst.status == STATUS_FINISHED:
                    # Only update if the translation isn't marked as finished.
                    continue

                # Fetch the Pootle store for the corresponding translation project and fill in the translations.
                store = Store.objects.get(
                    translation_project=request.translation_project)

                # Get all of the units
                units = store.unit_set.all()

                # Make sure that len(units) matches len(result)
                #                print units[0].source
                #                print result_sentences[0]
                #                print "----"
                #                print units[len(units) - 1].source
                #                print result_sentences[len(result_sentences)-1]
                #                print result_sentences[len(result_sentences)-2]

                # If the sentence length doesn't match, then we don't have a one-to-one correspondence
                # between sentences. Mark the translation request with an error
                if (len(units) != len(result_sentences)):
                    request.status = STATUS_ERROR
                    print "An error occurred with request %s" % request
                else:
                    # Start adding the translations to Pootle (lazy).
                    for i in range(0, len(units)):
                        #                        units[i].target = multistring(result_sentences[i])
                        units[i].target = result_sentences[i]
                        units[i].state = pootle_store.util.FUZZY
                        units[i].save()

                    # Set the status of the current TranslationRequest as completed
                    request.status = STATUS_FINISHED

                request.save()

            except ObjectDoesNotExist as ex:
                pass
Ejemplo n.º 4
0
    def act(self, population_dict, world, position_hash_table=None):
        """
        Method that decides and calls an action for the current timestep.
        Searches through custom methods and built-in movement methods.
        The action method specifically selects an action to take, from "move",
        "reproduce", "drink", and "eat". Then the appropriate instance method
        from this class is executed to yield the final list of affect
        organisms.

        Parameters
        ----------
        population_dict : dict of Organisms
            Dict of organisms, with which this organism may interact.
        world : World
            World, with which this organism may interact.
        position_hash_table : dict
            Dictionary mapping positions to available organisms.

        Returns
        -------
        affected_organisms : Organisms, or list of Organisms
            Organism or list of organisms affected by this organism's action.

        """
        action_name = None
        try:
            if self.custom_module_fns is not None:
                for custom_module in self._custom_modules:
                    if hasattr(custom_module, self.action_type):
                        action_name = getattr(custom_module, self.action_type)(
                            self,
                            population_dict,
                            world,
                            position_hash_table=position_hash_table)
            if action_name is None:
                action_name = getattr(action, self.action_type)(
                    self,
                    population_dict,
                    world,
                    position_hash_table=position_hash_table)
        except AttributeError as e:
            raise AttributeError(
                str(e) +
                '. Check that \'%s\' method is indeed ' % self.action_type +
                'contained within the provided custom modules and that the ' +
                'method is written correctly.').with_traceback(
                    sys.exc_info()[2])

        self.last_action = action_name

        affected_organisms = cast_to_list(
            getattr(self,
                    action_name)(population_dict,
                                 world,
                                 position_hash_table=position_hash_table))

        # Ensure this organism is included in affected_organisms
        already_included = False
        for org in affected_organisms:
            if org.organism_id == self.organism_id:
                already_included = True
        if not already_included:
            # e.g. unknown reason for exlusion, so default to death
            self.die('unknown', in_place=True)
            affected_organisms.append(self)

        return self, affected_organisms
Ejemplo n.º 5
0
def request_translation(translator, sentences, source_language, target_language):
    """
    Request a MachineTranslator to perform a translation. The request process is implemented
    based on the type of MachineTranslator. For example, a SERVERLAND type uses a MT Server Land
    to request a translation.
    Preconditions:
        translator:    A MachineTranslator object.
        sentences:     A list of strings.
    Exceptions:
        UnsupportedLanguagePair:The target translator doesn't support the language pair.
        UndefinedTranslator:    When looking up the ServerlandHost for a MachineTranslator, if none exists (this should not happen).
        ServerlandConfigError:  The ServerlandHost has an error.
    """
    
    # Make sure that the translator supports the language pair
    if not translator.is_language_pair_supported(source_language, target_language):
        raise UnsupportedLanguagePair(translator, source_language, target_language)
    
    # Generate a request id
    request_id = utils.generate_request_id()
    
    # Make sure that sentences is a list.
    sentences = utils.cast_to_list(sentences)
#    if not isinstance(sentences, list):
#        print "Retrieved only one sentence."
#        sentences = [sentences]
    
    # One sentence per line, to make it easier for the translator to do its job.
    text = "\n".join(sentence for sentence in sentences)
        
    # Determine the machine translator type.
    if translator.type == SERVERLAND:
        # Get the ServerlandHost
        try:
            # TODO: Change this host reference. Currently, only one ServerLand host is allowed.
            serverland_host = translator.serverlandhost_set.all()[0]
        except IndexError:
            raise UndefinedTranslator(translator)
        
        source_file_id = "%s-%s-%s" % (request_id, source_language.code, target_language.code)
        
        try:
#            print "Requesting the translation"
#            print serverland_host.token, request_id, translator.shortname
#            print utils.get_iso639_2(source_language.code), utils.get_iso639_2(target_language.code)
#            print source_file_id
#            print text
            
            # Request the translation.
            proxy = xmlrpclib.ServerProxy(serverland_host.url)
            result = proxy.create_translation(serverland_host.token,            # Authentication token
                                     request_id,                                # Custom request ID
                                     translator.shortname,                      # MT ServerLand worker
                                     utils.get_iso639_2(source_language.code),  # Source language (in bibliographic)
                                     utils.get_iso639_2(target_language.code),  # Target language (in bibliographic)
                                     source_file_id,                            # Composite id
                                     text)                                      # Sentence(s) to translate
            
            # TODO: For now, just print the results.
            print result
            
            # TODO: Return the request_id
            return request_id
        except xmlrpclib.Fault as ex:
            raise ServerlandConfigError(serverland_host, ex)
Ejemplo n.º 6
0
    def fetch_translations(self):
        proxy = xmlrpclib.ServerProxy(self.url)
        
        # Fetch the translation requests (and make sure the result is a list)
        requests = utils.cast_to_list(proxy.list_requests(self.token))
        
        # Retrieve the translation requests that are "ready"
        completedRequests = [request for request in requests if request['ready']]
        
        # Process the completed requests
        for completedRequest in completedRequests:
            # Get the result
            result = proxy.list_results(self.token, completedRequest['request_id'])
            
            # Get the external request id and sentences
            external_request_id = completedRequest['shortname']
            result_sentences = utils.clean_string(result['result'].strip()).split('\n')
            
            # FIXME: Add exception handling when the translation request is not found.
            try:
                # Look up the original translation request
                request = TranslationRequest.objects.get_by_external_id(external_request_id)
                
                # TODO: Should we delete the translations, or filter them some way in Serverland to prevent re-retrieving translations? This could get expensive...
                if requst.status == STATUS_FINISHED:
                    # Only update if the translation isn't marked as finished.
                    continue
                
                # Fetch the Pootle store for the corresponding translation project and fill in the translations.
                store = Store.objects.get(translation_project = request.translation_project)
                
                # Get all of the units
                units = store.unit_set.all()
                
                # Make sure that len(units) matches len(result)
#                print units[0].source
#                print result_sentences[0]
#                print "----"
#                print units[len(units) - 1].source
#                print result_sentences[len(result_sentences)-1]
#                print result_sentences[len(result_sentences)-2]
                
                # If the sentence length doesn't match, then we don't have a one-to-one correspondence
                # between sentences. Mark the translation request with an error
                if (len(units) != len(result_sentences)):
                    request.status = STATUS_ERROR
                    print "An error occurred with request %s" % request
                else:
                    # Start adding the translations to Pootle (lazy).
                    for i in range(0, len(units)):
#                        units[i].target = multistring(result_sentences[i])
                        units[i].target = result_sentences[i]
                        units[i].state = pootle_store.util.FUZZY
                        units[i].save()
                        
                    # Set the status of the current TranslationRequest as completed
                    request.status = STATUS_FINISHED
                    
                request.save()
                
            except ObjectDoesNotExist as ex:
                pass
Ejemplo n.º 7
0
def load_species_from_param_files(fns, init_world, custom_module_fns=None):
    """
    Load all available species parameter files.

    Parameters
    ----------
    fns : list of str
        Input filenames of species parameter files. Different species get
        different species parameter files, from which the individual organisms
        are initialized.
    init_world : World
        Initial World instance for this Universe.
    custom_module_fns : list of str
        List of external Python scripts containing custom organism
        behaviors. :mod:`blossom` will search for methods within each
        filename included here.

    Returns
    -------
    population_dict : dict of Organisms
        A dict of Organism objects constructed from the parameter file.

    """

    # Find organism filenames, can be a list of patterns
    fns = cast_to_list(fns)
    org_files = [fn for pattern in fns for fn in glob.glob(pattern)]

    # Initialize list of dictionaries to hold all organism parameters
    # Each dictionary contains parameters for a single species
    population_dict = {}
    for i, org_file in enumerate(org_files):
        # Initialize temporary dict to store species parameters
        species_init_dict = {}

        # Parameters that must be str or None
        param_str = [
            'species_name', 'movement_type', 'reproduction_type',
            'drinking_type', 'action_type', 'eating_type'
        ]

        # Parameters that must be int
        param_int = ['population_size', 'dna_length']

        # Parameters that must be int or 'None' or 'inf'
        param_int_none_inf = [
            'max_age', 'max_time_without_food', 'max_time_without_water',
            'mutation_rate', 'food_capacity', 'food_initial',
            'food_metabolism', 'food_intake', 'water_capacity',
            'water_initial', 'water_metabolism', 'water_intake'
        ]

        # Parameters that must be float
        param_float = [
            'proportion_m', 'proportion_f', 'proportion_a', 'proportion_h'
        ]

        # Parameters that must be bool
        param_bool = ['can_mutate']

        # Load from config file
        config_org = configparser.ConfigParser()
        config_org.read(org_file)

        # Cycle through all parameters in the config file,
        # converting them to proper types as specifed above
        for section in config_org.sections():
            for (key, val) in config_org.items(section):

                if key in param_str:
                    pass
                elif key in param_int:
                    val = int(val)
                elif key in param_int_none_inf:
                    if val != 'None' and type(val) not in [int, float]:
                        val = float(val)
                elif key in param_float:
                    val = float(val)
                elif key in param_bool:
                    val = (val == 'True')
                else:
                    print(key, val)
                    raise NameError('Key is not a valid parameter')
                # ensure 'None' parameters are set to None
                if val == 'None':
                    val = None
                species_init_dict[key] = val

        # Track custom method file paths
        species_init_dict['custom_module_fns'] = custom_module_fns

        species_organism_list = create_organisms(species_init_dict, init_world)

        # Populate population dict with relevant bulk stats and organism lists
        population_dict[species_init_dict['species_name']] = {
            'statistics': {
                'total': species_init_dict['population_size'],
                'alive': species_init_dict['population_size'],
                'dead': 0
            },
            'organisms': species_organism_list
        }

    return population_dict
Ejemplo n.º 8
0
def load_species_from_dict(init_dicts, init_world, custom_module_fns=None):
    """
    Create a list of organisms loaded from Python dicts.

    Parameters
    ----------
    init_dicts : list of dict
        Input species dictionaries from which the individual organisms
        are initialized. Each dictionary is for a different species.
    init_world : World
        Initial World instance for this Universe.
    custom_module_fns : list of str
        List of external Python scripts containing custom organism
        behaviors. :mod:`blossom` will search for methods within each
        filename included here.

    Returns
    -------
    population_dict : dict of Organisms
        A dict of Organism objects constructed from the parameter file.

    """
    init_dicts = cast_to_list(init_dicts)

    population_dict = {}
    for init_dict in init_dicts:

        species_init_dict = {}

        # Set up defaults based on species parameters
        for (field, default) in default_fields.species_fields.items():
            species_init_dict[field] = init_dict.get(field, default)

        # Set up custom fields provided in initialization dictionary
        init_keys = set(init_dict.keys())
        default_keys = set(default_fields.species_fields.keys())
        for custom_field in (init_keys - default_keys):
            species_init_dict[custom_field] = init_dict[custom_field]

        assert 'population_size' in init_dict
        population_size = init_dict['population_size']
        assert type(population_size) is int
        species_init_dict['population_size'] = population_size

        assert type(species_init_dict['species_name']) == str

        for field in [
                'movement_type', 'reproduction_type', 'drinking_type',
                'eating_type', 'action_type'
        ]:
            assert (species_init_dict[field] is None
                    or type(species_init_dict[field]) is str)

        for field in ['dna_length']:
            assert type(species_init_dict[field]) is int

        if species_init_dict['drinking_type']:
            assert (species_init_dict['water_capacity'] is not None
                    and species_init_dict['water_initial'] is not None
                    and species_init_dict['water_metabolism'] is not None
                    and species_init_dict['water_intake'] is not None and
                    species_init_dict['max_time_without_water'] is not None)
        if species_init_dict['eating_type']:
            assert (species_init_dict['food_capacity'] is not None
                    and species_init_dict['food_initial'] is not None
                    and species_init_dict['food_metabolism'] is not None
                    and species_init_dict['food_intake'] is not None
                    and species_init_dict['max_time_without_food'] is not None)

        for field in [
                'max_age', 'max_time_without_food', 'max_time_without_water',
                'mutation_rate', 'food_capacity', 'food_initial',
                'food_metabolism', 'food_intake', 'water_capacity',
                'water_initial', 'water_metabolism', 'water_intake'
        ]:
            if type(species_init_dict[field]) is list:
                assert (len(species_init_dict[field]) == population_size)
            elif type(species_init_dict[field]) in [int, float]:
                species_init_dict[field] = ([species_init_dict[field]] *
                                            population_size)
            else:
                assert species_init_dict[field] is None

        if not species_init_dict['custom_module_fns']:
            # Track custom method file paths
            species_init_dict['custom_module_fns'] = custom_module_fns

        if 'initial_positions' in init_dict:
            assert len(init_dict['initial_positions']) == population_size
            for position in init_dict['initial_positions']:
                assert len(position) == init_world.dimensionality
            species_init_dict['initial_positions'] \
                = init_dict['initial_positions']

        species_organism_list = create_organisms(species_init_dict, init_world)

        # Populate population dict with relevant bulk stats and organism lists
        population_dict[species_init_dict['species_name']] = {
            'statistics': {
                'total': population_size,
                'alive': population_size,
                'dead': 0
            },
            'organisms': species_organism_list
        }

    return population_dict