def _log_transformation(source, result, trans=None, implicit=False): if result is None or not config.get_option('log_transformations') or \ (trans is not None and not trans._loggable): return result if isiterable(result): return (_log_transformation(source, r, trans) for r in result) # Converters are no longer restricted to Stim inputs, so ensure name and # filename are set. name = getattr(source, 'name', None) filename = getattr(source, 'filename', None) values = [name, filename, source.__class__.__name__] if isinstance(result, Stim): values.extend([result.name, result.filename]) else: values.extend(['', '']) values.append(result.__class__.__name__) if trans is not None: values.append(trans.__class__.__name__) tr_attrs = [getattr(trans, attr) for attr in trans._log_attributes] values.append(str(dict(zip(trans._log_attributes, tr_attrs)))) else: values.append(['', '']) parent = source.history string = str(parent) if parent else values[2] string += '->{}/{}'.format(values[6], values[5]) values.extend([string, parent]) values.append(implicit) result.history = TransformationLog(*values) return result
def _log_transformation(source, result, trans=None): if result is None or not config.get_option('log_transformations') or \ (trans is not None and not trans._loggable): return result if isiterable(result): return (_log_transformation(source, r, trans) for r in result) values = [source.name, source.filename, source.__class__.__name__] if isinstance(result, Stim): values.extend([result.name, result.filename]) else: values.extend(['', '']) values.append(result.__class__.__name__) if trans is not None: values.append(trans.__class__.__name__) tr_attrs = [getattr(trans, attr) for attr in trans._log_attributes] values.append(str(dict(zip(trans._log_attributes, tr_attrs)))) else: values.append(['', '']) parent = source.history string = str(parent) if parent else values[2] string += '->%s/%s' % (values[6], values[5]) values.extend([string, parent]) result.history = TransformationLog(*values) return result
def transform(self, stims, *args, **kwargs): if isinstance(stims, string_types): stims = load_stims(stims) # If stims is a CompoundStim and the Transformer is expecting a single # input type, extract all matching stims if isinstance(stims, CompoundStim) and not isinstance( self._input_type, tuple): stims = stims.get_stim(self._input_type, return_all=True) if not stims: raise ValueError("No stims of class %s found in the provided" "CompoundStim instance." % self._input_type) # If stims is an iterable, naively loop over elements, removing # invalid results if needed if isiterable(stims): iters = self._iterate(stims, *args, **kwargs) if config.drop_bad_extractor_results: iters = (i for i in iters if i is not None) return progress_bar_wrapper(iters, desc='Stim') # Validate stim, and then either pass it directly to the Transformer # or, if a conversion occurred, recurse. else: validated_stim = self._validate(stims) # If a conversion occurred during validation, we recurse if stims is not validated_stim: return self.transform(validated_stim, *args, **kwargs) else: result = self._transform(validated_stim, *args, **kwargs) result = _log_transformation(validated_stim, result, self) if isgenerator(result): result = list(result) return result
def _transform(self, stim, *args, **kwargs): # Check if we are requesting faster than the rate limit, # if so, throttle by sleeping time_diff = time.time() - self._last_request_time if time_diff < self.rate_limit: time.sleep(self.rate_limit - time_diff) self._last_request_time = time.time() # Check if we are trying to transform a large amount of data self.transformed_stim_count += len(listify(stim)) if not config.get_option('allow_large_jobs'): if not isiterable(stim) and stim.duration \ and stim.duration > config.get_option('long_job'): raise ValueError("Attempted to run an API transformation " "on a stimulus of duration %f, aborting. " "To allow this transformation, set " "config option 'allow_large_jobs' to " "True." % stim.duration) if self.transformed_stim_count > config.get_option('large_job'): raise ValueError("Number of transformations using this %s " "would exceed %d, aborting further " "transformations. To allow, set config " "option 'allow_large_jobs' to True." % (self.__class__.__name__, config.get_option('large_job'))) if config.get_option('api_key_validation') and not self.validate_keys(): raise ValueError("Error running %s, a provided environment key " "was invalid or unauthorized. Please check that " "you have authorized credentials for accessing " "the target API." % self.__class__.__name__) return super(APITransformer, self)._transform(stim, *args, **kwargs)
def _log_transformation(source, result, trans=None, implicit=False): if result is None or not config.get_option('log_transformations') or \ (trans is not None and not trans._loggable): return result if isiterable(result): return (_log_transformation(source, r, trans) for r in result) values = [source.name, source.filename, source.__class__.__name__] if isinstance(result, Stim): values.extend([result.name, result.filename]) else: values.extend(['', '']) values.append(result.__class__.__name__) if trans is not None: values.append(trans.__class__.__name__) tr_attrs = [getattr(trans, attr) for attr in trans._log_attributes] values.append(str(dict(zip(trans._log_attributes, tr_attrs)))) else: values.append(['', '']) parent = source.history string = str(parent) if parent else values[2] string += '->%s/%s' % (values[6], values[5]) values.extend([string, parent]) values.append(implicit) result.history = TransformationLog(*values) return result
def _transform(self, stim, *args, **kwargs): stims = listify(stim) if all(self._stim_matches_input_types(s) for s in stims): result = super() \ ._transform(stims, *args, **kwargs) if isiterable(stim): return result else: return result[0] else: return list(super()._iterate(stims, *args, **kwargs))
def _propagate_context(self, stim, result): if isiterable(result): for r in result: self._propagate_context(stim, r) else: if result.onset is None: result.onset = stim.onset if result.duration is None: result.duration = stim.duration if result.order is None: result.order = stim.order
def _extract(self, stim): outputs = [] if self.subset_idx is not None: idx_diff = set(self.subset_idx) - set(stim.data.index) idx_int = set(self.subset_idx) & set(stim.data.index) if idx_diff: logging.warning(f'{idx_diff} not in index.') if not idx_int: raise ValueError('No valid index') series = stim.data[idx_int] else: series = stim.data for f in self.functions: metrics = f(series, **self.kwargs) if isiterable(metrics): metrics = np.array(metrics) outputs.append(metrics) return ExtractorResult([outputs], stim, self, self.var_names)
def transform(self, stims, validation='strict', *args, **kwargs): ''' Executes the transformation on the passed stim(s). Args: stims (str, Stim, list): One or more stimuli to process. Must be one of: - A string giving the path to a file that can be read in as a Stim (e.g., a .txt file, .jpg image, etc.) - A Stim instance of any type. - An iterable of stims, where each element is either a string or a Stim. validation (str): String specifying how validation errors should be handled. Must be one of: - 'strict': Raise an exception on any validation error - 'warn': Issue a warning for all validation errors - 'loose': Silently ignore all validation errors args: Optional positional arguments to pass onto the internal _transform call. kwargs: Optional positional arguments to pass onto the internal _transform call. ''' if isinstance(stims, str): stims = load_stims(stims) # If stims is a CompoundStim and the Transformer is expecting a single # input type, extract all matching stims if isinstance(stims, CompoundStim) and not isinstance( self._input_type, tuple): stims = stims.get_stim(self._input_type, return_all=True) if not stims: raise ValueError("No stims of class %s found in the provided" "CompoundStim instance." % self._input_type) # If stims is an iterable, naively loop over elements, removing # invalid results if needed if isiterable(stims): iters = self._iterate(stims, validation=validation, *args, **kwargs) if config.get_option('drop_bad_extractor_results'): iters = (i for i in iters if i is not None) iters = progress_bar_wrapper(iters, desc='Stim') return set_iterable_type(iters) # Validate stim, and then either pass it directly to the Transformer # or, if a conversion occurred, recurse. else: try: validated_stim = self._validate(stims) except TypeError as err: if validation == 'strict': raise err elif validation == 'warn': logging.warning(str(err)) return elif validation == 'loose': return # If a conversion occurred during validation, we recurse if stims is not validated_stim: return self.transform(validated_stim, *args, **kwargs) else: result = self._transform(validated_stim, *args, **kwargs) result = _log_transformation(validated_stim, result, self) if isgenerator(result): result = list(result) self._propagate_context(validated_stim, result) return result