def init(self): self.programs = check_programs_existence(programs=['mencoder']) for p in self.programs: self.info('Using %13s = %s' % (p, self.programs[p])) if not isinstance(self.config.file, str): raise BadConfig('This should be a string.', self, 'file') self.file = expand(self.config.file) if not os.path.exists(self.file): msg = 'File %r does not exist.' % self.file raise BadConfig(msg, self, 'file') timestamps_file = self.file + MPlayer.TIMESTAMPS_SUFFIX if os.path.exists(timestamps_file): self.info('Reading timestamps from %r.' % timestamps_file) self.timestamps = open(timestamps_file) else: self.timestamps = None #self.info('Will use fps for timestamps.') self.mencoder_started = False self.state.timestamp = None self.state.timestamp = self.get_next_timestamp() self.state.next_frame = None self.state.finished = False self.num_frames_read = 0
def update(self): # TODO: add check if self.state.first_timestamp is None: self.state.first_timestamp = self.get_input_timestamp(0) self.state.frame = 0 else: self.state.frame += 1 # Add stats macros = {} macros['timestamp'] = self.get_input_timestamp(0) if self.state.first_timestamp == ETERNITY: macros['time'] = -1 else: macros['time'] = \ self.get_input_timestamp(0) - self.state.first_timestamp macros['frame'] = self.state.frame rgb = self.input.rgb im = Image_from_array(rgb) from . import ImageDraw draw = ImageDraw.Draw(im) # {string: "raw image", position: [10,30], halign: left, # color: black, bg: white } if not isinstance(self.config.texts, list): raise BadConfig('Expected list', self, 'texts') for text in self.config.texts: text = text.copy() if not 'string' in text: raise BadConfig('Missing field "string" in text spec %s.' % text.__repr__(), self, 'texts') try: text['string'] = Text.replace(text['string'], macros) except KeyError as e: msg = str(e) + '\nAvailable: %s.' % macros.keys() raise BadConfig(msg, self, 'texts') p = text['position'] try: p[0] = get_ver_pos_value(p[0], height=rgb.shape[0]) p[1] = get_hor_pos_value(p[1], width=rgb.shape[1]) except ValueError as e: raise BadConfig(str(e), text.__repr__(), self, 'texts') process_text(draw, text) out = im.convert("RGB") pixel_data = numpy.asarray(out) self.output.rgb = pixel_data
def apply_styles(self, pylab): # TODO: check type for style in self.config.fancy_styles: if not style in fancy_styles: error = ('Cannot find style %r in %s' % (style, fancy_styles.keys())) raise BadConfig(error, self, 'style') function = fancy_styles[style] function(pylab)
def get_output_signals(self): self.reader = self.config.file all_signals = self.reader.get_all_signals() if self.config.signals is None: self.signals = all_signals else: signal_list = filter(lambda x: x, self.config.signals.split(',')) if not signal_list: msg = 'Bad format: %r.' % self.config.signals raise BadConfig(msg, self, 'signals') for s in signal_list: if not s in all_signals: msg = ('Signal %r not present in log (available: %r)' % (s, all_signals)) raise BadConfig(msg, self, 'signals') self.signals.append(s) return self.signals
def init(self): dirname = self.config.dir dirname = expand(dirname) if not os.path.exists(dirname): raise BadConfig('Not existent directory %r.' % dirname, self, 'dir') if not os.path.isdir(dirname): raise BadConfig('The file %r is not a directory.' % dirname, self, 'dir') regexp = self.config.regexp # TODO: use proper logging self.info("Reading %r from %r." % (regexp, dirname)) all_files = os.listdir(dirname) selected = [os.path.join(dirname, f) for f in all_files if re.match(regexp, f)] def natural_key(string): """See http://www.codinghorror.com/blog/archives/001018.html""" return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string)] selected.sort(key=lambda x: natural_key(os.path.basename(x))) self.info("Selected %d/%d files." % (len(selected), len(all_files))) fps = float(self.config.fps) if fps <= 0: raise BadConfig(self, "Invalid fps value %s." % fps, 'fps') # tuples (timestamp, filename) frames = [(i / fps, f) for i, f in enumerate(selected)] if not frames: raise Exception('No frames found in dir %r.' % dirname) self.state.frames = frames self.state.next_frame = 0
def get_iterator(self): filename = self.config.filename if not os.path.exists(filename): raise BadConfig(self, 'Not existent file %r.' % filename, 'filename') raw_events = aer_load_log_generic(filename) events2 = aer_raw_relative_timestamp(raw_events) for e in events2: yield 0, e['timestamp'], e
def get_output_signals(self): import rosbag self.bag = rosbag.Bag(self.config.file) self.topics = self.get_topics() self.topic2signal = {} signals = [] for t in self.topics: self.info(t) if ':' in t: tokens = t.split(':') assert len(tokens) == 2 t = tokens[0] signal_name = tokens[1] else: signal_name = str(t).split('/')[-1] if signal_name in signals: self.error('Warning: repeated name %s' % signal_name) signal_name = ("%s" % t).replace('/', '_') self.error('Using long form %r.' % signal_name) signals.append(signal_name) self.topic2signal[t] = signal_name topics = self.topic2signal.keys() self.info(self.topic2signal) limit = self.config.limit if not isinstance(limit, (float, int)): msg = 'I require a number; 0 for none.' raise BadConfig(msg, self, 'limit') if self.config.t0 is not None or self.config.t1 is not None: t0 = self.config.t0 t1 = self.config.t1 start_time, end_time = self._get_start_end_time_t0_t1(t0, t1) else: start_time, end_time = self._get_start_end_time(limit) print('t0: %s' % self.config.t0) print('t1: %s' % self.config.t1) print('start_time: %s' % start_time) print('end_time: %s' % end_time) print('start_stamp: %s' % self.start_stamp) print('end_stamp: %s' % self.end_stamp) params = dict(topics=topics, start_time=start_time, end_time=end_time) self.iterator = self.bag.read_messages(**params) return signals
def choose(rgb, channel=0): ''' Chooses a channel from an rgb image and replicates it over the other two. Raises an error if ``channel`` is invalid. :param rgb: Input image. :param channel: Which channel to choose. :return: processed: The processed image. ''' if not channel in [0,1,2]: raise BadConfig('Invalid channel specified.', config='channel') v = rgb[:,:,channel] return numpy.dstack((v,v,v))
def init(self): self.format = self.config.format (w, h) = self.get_shape() self.total_width = w self.total_height = h self.frame = 0 if self.format == 'pdf': self.init_pdf() elif self.format == 'png': self.init_png() else: raise BadConfig('Invalid format %r.' % self.format, self, 'format') self.count = 0 self.fps = None self.t0 = None self.tmp_cr = None
def init(self): filename = self.config.file filename = os.path.expandvars(filename) filename = os.path.expanduser(filename) if not os.path.exists(filename): raise BadConfig('File %r does not exist.' % filename, self, 'file') # TODO: add .gz if filename.endswith('bz2'): import bz2 self.stream = bz2.BZ2File(filename) else: self.stream = open(filename, 'r') self.state.line = 0 # line counter self.read_next_line() if self.timestamp is None: raise Exception('Empty file %s' % filename)
def init(self): # Find the required files files = glob.glob(self.config.files) if len(files) == 0: raise BadConfig( 'No files correspond to the pattern %r.' % self.config.files, self, 'files') # Open all logs; make sure they have the required signals and # note their initial timestamp. # list(tuple(file, timestamp, signal2table)) logs = [] for f in files: hf = tc_open_for_reading(f) check_is_procgraph_log(hf) log_group = hf.root._f_getChild(PROCGRAPH_LOG_GROUP) log_signals = list(log_group._v_children) signal2table = {} for s in self.signals: if not s in log_signals: raise Exception('Log %r does not have signal %r ' '(it has %s).' % (f, s, log_signals)) signal2table[s] = log_group._f_getChild(s) timestamp = signal2table[s][0]['time'] logs.append((hf, timestamp, signal2table)) # Sort them by timestamp self.logs = sorted(logs, key=operator.itemgetter(1)) self.current_log = None for log in logs: filename = log[0].filename length = len(list(log[2].values())[0]) self.status('- queued log (%6d rows) from %r' % (length, filename)) self.start_reading_next_log()
def update(self): if not self.all_input_signals_ready(): return n = self.num_input_signals() for i in range(n): input_check_convertible_to_rgb(self, i) cols = self.config.cols if cols is not None and not isinstance(cols, int): raise BadConfig('Expected an integer.', self, 'cols') images = [self.get_input(i) for i in range(n)] images = map(torgb, images) canvas = make_images_grid(images, cols=self.config.cols, pad=self.config.pad, bgcolor=self.config.bgcolor) self.set_output(0, canvas)
def update(self): self.limits = None start = time.clock() if self.figure is None: self.init_figure() pylab.figure(self.figure.number) self.apply_styles(pylab) for i in range(self.num_input_signals()): value = self.input[i] if value is None: raise BadInput('Input is None (did you forget a |sync|?)', self, i) elif isinstance(value, tuple): if len(value) != 2: raise BadInput( 'Expected tuple of length 2 instead of %d.' % len(value), self, i) xo = value[0] yo = value[1] if xo is None or yo is None: raise BadInput('Invalid members of tuple', self, i) x = np.array(xo) y = np.array(yo) # X must be one-dimensional if len(x.shape) > 1: raise BadInput('Bad x vector w/shape %s.' % str(x.shape), self, i) # y should be of dimensions ...? if len(y.shape) > 2: raise BadInput('Bad shape for y vector %s.' % str(y.shape), self, i) if len(x) != y.shape[0]: raise BadInput('Incompatible dimensions x: %s, y: %s' % (str(x.shape), str(y.shape))) # TODO: check x unidimensional (T) # TODO: check y compatible dimensions (T x N) else: y = np.array(value) if len(y.shape) > 2: raise BadInput('Bad shape for y vector %s.' % str(y.shape), self, i) if len(y.shape) == 1: x = np.array(range(len(y))) else: assert (len(y.shape) == 2) x = np.array(range(y.shape[1])) if len(x) <= 1: continue if len(y.shape) == 2: y = y.transpose() if len(y.shape) == 1: pid = self.canonicalize_input(i) self.plot_one(pid, x, y, self.config.format) else: assert (len(y.shape) == 2) num_lines = y.shape[0] for k in range(num_lines): pid = "%s-%d" % (self.canonicalize_input(i), k) yk = y[k, :] self.plot_one(pid, x, yk, self.config.format) # TODO: check that if one has time vector, also others have it if self.limits is not None: if self.config.x_min is not None: self.limits[0] = self.config.x_min if self.config.x_max is not None: self.limits[1] = self.config.x_max if self.config.y_min is not None: self.limits[2] = self.config.y_min if self.config.y_max is not None: self.limits[3] = self.config.y_max if self.config.symmetric: if self.config.y_min is not None or \ self.config.y_max is not None: raise BadConfig( 'Cannot specify symmetric together with' 'y_min or y_max.', self, 'symmetric') M = max(abs(self.limits[2:4])) if 'dottedzero' in self.config.fancy_styles: a = pylab.axis() pylab.plot([a[0], a[1]], [0, 0], 'k--') self.limits[2] = -M self.limits[3] = M # leave some space above and below self.limits[2] = self.limits[2] * 1.1 self.limits[3] = self.limits[3] * 1.1 self.axes.axis(self.limits) if self.legend_handle is None: legend = self.config.legend if legend: self.legend_handle = self.axes.legend(*legend, loc='upper right', handlelength=1.5, markerscale=2, labelspacing=0.03, borderpad=0, handletextpad=0.03, borderaxespad=1) # http://matplotlib.sourceforge.net/users/tight_layout_guide.html try: pylab.tight_layout() except Exception as e: msg = ('Could not call tight_layout(); available only on ' 'Matplotlib >=1.1 (%s)' % e) if not self.warned: self.warning(msg) self.warned = True plotting = time.clock() - start start = time.clock() # There is a bug that makes the image smaller than desired # if tight is True pixel_data = pylab2rgb(transparent=self.config.transparent, tight=self.config.tight) # So we check and compensate shape = pixel_data.shape[0:2] shape_expected = (self.config.height, self.config.width) from procgraph_images import image_pad # need here, otherwise circular if shape != shape_expected: msg = ('pylab2rgb() returned size %s instead of %s.' % (shape, shape_expected)) msg += ' I will pad the image with white.' self.warning(msg) pixel_data = image_pad(pixel_data, shape_expected, bgcolor=[1, 1, 1]) assert_equal(pixel_data.shape[0:2], shape_expected) reading = time.clock() - start if False: # 30 49 30 before print("plotting: %dms reading: %dms" % (plotting * 1000, reading * 1000)) self.output.rgb = pixel_data if not self.config.keep: pylab.close(self.figure.number) self.figure = None
def get_output_signals(self): self.signals = filter(lambda x: x, self.config.signals.split(',')) if not self.signals: raise BadConfig('No signals specified.', self, 'signals') return self.signals