예제 #1
0
    def update(self, **kwargs) -> 'Property':
        '''Updates the current value

        The method `update()` sets the property `current_value`
        as the output of the method `sample()`. Will only update
        once per resolve.

        Any object that implements the method `update()` will have it called.

        Returns
        -------
        Property
            Returns itself.

        '''

        if self.has_updated_since_last_resolve:
            return self

        self.has_updated_since_last_resolve = True

        if hasmethod(self.sampling_rule, "update"):
            self.sampling_rule.update(**kwargs)

        self.current_value = self.sample(self.sampling_rule, **kwargs)

        return self
예제 #2
0
    def update(self, **kwargs) -> 'Property':
        '''Updates the current value

        The method `update()` sets the property `current_value`
        as the output of the method `sample()`. Will only update
        once per resolve.

        Any object that implements the method `update()` will have it called.

        Returns
        -------
        Property
            Returns itself.

        '''
        
        provided_key = kwargs.get("_update_key", False) or deeptrack.features._SESSION_STRUCT["update_key"]

        if self.last_update_id == provided_key:
            return self
        

        
        self.last_update_id = provided_key

        if hasmethod(self.sampling_rule, "update") and not isinstance(self.sampling_rule, dict):
            self.sampling_rule.update(**kwargs)
        
        self.current_value = self.sample(self.sampling_rule, **kwargs)

        return self
예제 #3
0
    def update(self, **kwargs) -> 'Property':
        r'''Updates the current value

        The method `update()` sets the property `current_value`
        as the output of the method `sample()`.

        Returns
        -------
        Property
            Returns itself.

        '''

        if not kwargs.get("force_update", False) and self.has_updated_since_last_resolve:
            return self
        
        self.has_updated_since_last_resolve = True

        if hasmethod(self.sampling_rule, "update"):
            self.sampling_rule.update(**kwargs)

        self.current_value = self.sample(self.sampling_rule, **kwargs)

        return self
예제 #4
0
    def sample(self, sampling_rule, **kwargs):
        '''Samples the sampling rule

        Returns a sampled instance of the `sampling_rule` field.
        The logic behind the sampling depends on the type of
        `sampling_rule`. These are checked in the following order of
        priority:

        1. Any object with a callable `sample()` method has this
            method called and returned.
        2. If the rule is a ``dict``, sample each value and combine the 
            result into a new ``dict`` using the original keys.
        3. If the rule is a ``list``, sample each element of the list and
            combine the result into a ne ``list``.
        4. If the rule is an ``iterable``, return the next output.
        5. If the rule is callable, call it with its accepted arguments.
            Example arguments can be the value of some other property.
        6. If none of the above apply, return the rule itself.
        
        Parameters
        ----------
        sampling_rule : any
            The rule to sample values from.
        **kwargs
            Arguments that will be passed on to functions that accepts them.

        Returns
        -------
        any
            A sampled instance of the `sampling_rule`.

        '''

        if hasmethod(sampling_rule, "sample"):
            # If the ruleset itself implements a sample method,
            # call it instead.
            return sampling_rule.sample(**kwargs)

        elif isinstance(sampling_rule, dict):
            # If the ruleset is a dict, return a new dict with each
            # element being sampled from the original dict.
            out = {}
            for key, val in self.sampling_rule.items():
                out[key] = self.sample(val, **kwargs)
            return out

        elif isinstance(sampling_rule, list):
            return [self.sample(item, **kwargs) for item in sampling_rule]

        elif isinstance(sampling_rule, (tuple, np.ndarray)):
            # tuple and ndarrays are elementary
            return sampling_rule

        elif isiterable(sampling_rule):
            # If it's iterable, return the next value
            try:
                return next(sampling_rule)
            except StopIteration:
                return self.current_value

        elif callable(sampling_rule):
            # If it's a function, extract the arguments it accepts.
            function_input = {}

            # Get the kwarg arguments the function accepts
            for key in get_kwarg_names(sampling_rule):
                # If that name is among passed kwarg arguments
                if key in kwargs:
                    if isinstance(kwargs[key], Property):
                        # If it is a property, update it and pass the current value
                        kwargs[key].update(**kwargs)

                        if isinstance(kwargs[key], SequentialProperty):
                            kwargs[key] = kwargs[key].current_value[
                                kwargs["sequence_step"]]
                        else:
                            kwargs[key] = kwargs[key].current_value

                    function_input[key] = kwargs[key]

            return sampling_rule(**function_input)

        else:
            # Else, assume it's elementary.
            return sampling_rule
예제 #5
0
    def sample(self, sampling_rule, **kwargs):
        r'''Samples the sampling rule

        Returns a sampled instance of the `sampling_rule` field.
        The logic behind the sampling depends on the type of
        `sampling_rule`. These are checked in the following order of
        priority:

        1. Any object with a callable `sample()` method has this
            method called and returned.
        2. If the rule is a ``dict``, the ``dict`` is copied and any value
            with has a callable sample method is replaced with the
            output of that call.
        3. If the rule is a ``list`` or a 1-dimensional ``ndarray``, return
        4. If the rule is an ``iterable``, return the next output.
        5. If the rule is callable, return the output of a call with
            no input parameters.
            a single element drawn from that ``list``/``ndarray``.
        6. If none of the above apply, return the rule itself.

        Returns
        -------
        any
            A sampled instance of the `sampling_rule`.

        '''

        if hasmethod(sampling_rule, "sample"):
            # If the ruleset itself implements a sample method,
            # call it instead.
            return sampling_rule.sample(**kwargs)

        elif isinstance(sampling_rule, dict):
            # If the ruleset is a dict, return a new dict with each
            # element being sampled from the original dict.
            out = {}
            for key, val in self.sampling_rule.items():
                    out[key] = self.sample(val, **kwargs)
            return out

        elif isinstance(sampling_rule, list):
            return [self.sample(item, **kwargs) for item in sampling_rule]

        elif isinstance(sampling_rule, (tuple, np.ndarray)):
            # tuple and ndarrays are elementary
            return sampling_rule

        elif isiterable(sampling_rule):
            # If it's iterable, return the next value
            try:
                return next(sampling_rule)
            except StopIteration:
                return self.current_value
  
        elif callable(sampling_rule):
            # If it's a function
            function_input = {}
            for key in get_kwarg_names(sampling_rule):
                if key in kwargs:
                    if isinstance(kwargs[key], Property):
                        kwargs[key].update(**kwargs)
                        
                        if isinstance(kwargs[key], SequentialProperty):
                            kwargs[key] = kwargs[key].current_value[kwargs["sequence_step"]]
                        else:
                            kwargs[key] = kwargs[key].current_value

                    
                         
                    function_input[key] = kwargs[key]

            return sampling_rule(**function_input)
            
        else:
            # Else, assume it's elementary.
            return sampling_rule
예제 #6
0
 def test_hasmethod(self):
     self.assertTrue(utils.hasmethod(utils, "hasmethod"))
     self.assertFalse(
         utils.hasmethod(utils, "this_is_definetely_not_a_method_of_utils"))