def __getitem__(self, index): """ Retreives items in index by looping through inputs as many times as needed. """ # TODO: Check if index exceeds length, either explicitly or implicitly. # Sort index index = sorted(index_to_list(index)) above = [i for i in index if i >= self.position] # Go forward to reach these below = [i for i in index if i < self.position ] # Will have to reset the loop to reach these if len(above) > 0: above_values = fireworks.cat( [self.step_forward(i + 1) for i in above]) else: above_values = Message() if len(below) > 0: self.reset() # Position will now be reset to 0 below_values = fireworks.cat( [self.step_forward(i + 1) for i in below]) else: below_values = Message() return below_values.append( above_values ) # TODO: Resort this message so values are in the order requested by index
def step_forward(self, n): """ Steps forward through inputs until position = n and then returns that value. This also updates the internal length variable if the iterator ends due to this method call. """ if self.length is not None and n > self.length: raise IndexError( "Requested index is out of bounds for inputs with length {0}.". format(self.length)) if n < self.position: raise IndexError( "Can only step forward to a value higher than current position." ) x = Message() for _ in range(n - self.position): try: # x = x.append(fireworks.merge([Pipe.__next__() for Pipe in self.inputs.values()])) # x = fireworks.merge([pipe.__next__() for pipe in self.inputs.values()]) x = self.input.__next__() self.position += 1 except StopIteration: self.length = self.position raise IndexError( "Requested index is out of bounds for inputs with length {0}." .format(self.length)) return x
def __init__(self, input_indices, output_indices, *args, **kwargs): super().__init__(*args, **kwargs) self.check_input() if len(input_indices) != len(output_indices): raise ValueError( "The number of input indices does not match the number of output indices." ) self.pointers = UnlimitedCache() self.pointers[input_indices] = Message({'output': output_indices}) self._current_index = 0
def write(self, params, metrics): # if len(params) != len(metrics): # raise ValueError("Parameters and Metrics messages must be equal length.") params = Message(params) for key, metric in metrics.items(): self.computed_metrics[key] = self.computed_metrics[key].append(metric) self.metrics_pipes[key].insert(metric) self.metrics_pipes[key].commit() self.params = self.params.append(params) self.params_pipe.insert(params) self.params_pipe.commit()
def __next__(self): """ Each iteration through a SeqIO object will produce a named tuple. This Pipe converts that tuple to a Message and produces the result. """ gene = self.seq.__next__() try: return Message({ 'sequences': [str(gene.seq)], 'ids': [gene.id], 'names': [gene.name], 'descriptions': [gene.description], 'dbxrefs': [gene.dbxrefs], }) except StopIteration: raise StopIteration
def init_metadata(self): """ Initializes metadata table. This is a necessary action whenever using an SQLalchemy table for the first time and is idempotent, so calling this method multiple times does not produce side-effects. """ self.metadata = db.TablePipe( metadata_table, self.engine, columns=['name', 'iteration', 'description', 'timestamp']) self.metadata.insert( Message({ 'name': [self.name], 'iteration': [self.iteration], 'description': [self.description], 'timestamp': [self.timestamp] })) self.metadata.commit()
def to_message(row, columns_and_types=None): """ Converts a database query result produced by SQLalchemy into a Message Args: row: A row from the query. columns_and_types (dict): If unspecified, this will be inferred. Otherwise, you can specify the columns to parse, for example, if you only want to extract some columns. Returns: message: Message representation of input. """ if columns_and_types is None: columns_and_types = parse_columns_and_types(row) row_dict = {c: [getattr(row, c)] for c in columns_and_types.keys()} return Message(row_dict)
def get_connection(self): self.params = Message() self.computed_metrics = defaultdict(Message)