#!/usr/bin/env python3 import sys from datetime import datetime import numpy as np import matplotlib.pyplot as pp from matplotlib.dates import MinuteLocator, HourLocator, DateFormatter, drange, date2num from matplotlib.ticker import MultipleLocator accumulation = sys.argv[1] resolution = int(sys.argv[2]) logname = sys.argv[3] outname = sys.argv[4] print(f"Accumulation: {accumulation}") print(f"Resolution: {resolution} seconds") print(f"Input Log: {logname}") print(f"Output Image: {outname}") accumulate = { "avg": np.mean, "peak": np.max, }[accumulation] data = -1000 * np.ones((86400//resolution, 1024), dtype=float) counts = np.zeros(86400//resolution, dtype=int) basetime = None last_lineidx = 0 accumulated_data = [] with open(logname, 'r') as logfile: for line in logfile: parts = line.split(";", maxsplit=1) timestamp = float(parts[0]) if not basetime: basetime = np.floor(timestamp / 86400) * 86400 lineidx = int((timestamp - basetime) // resolution) if lineidx != last_lineidx: if len(accumulated_data) != 0: # apply the accumulation function data[last_lineidx] = accumulate(np.array(accumulated_data).astype(float), 0) accumulated_data = [] last_lineidx = lineidx tmp_data = np.fromstring(parts[1], sep=";", dtype=int) if tmp_data.size == 1024: accumulated_data.append(tmp_data) else: print(f"Warning: line ignored due to wrong number of elements: has {tmp_data.size}, expected 1024.") x = np.linspace(0, 30, data.shape[1]) y = np.linspace(basetime, basetime + resolution * data.shape[0]) extent = [ 0, # MHz 30, # MHz date2num(datetime.utcfromtimestamp(basetime + resolution * data.shape[0])), date2num(datetime.utcfromtimestamp(basetime))] fig_x_scale = 0.85 fig_y_scale = 0.90 fig_x_off = 0.05 fig_y_off = 0.05 dpi = pp.rcParams['figure.dpi'] #get the default dpi value fig_size = (data.shape[1]/dpi/fig_x_scale, data.shape[0]/dpi/fig_y_scale) # convert pixels to DPI fix, ax = pp.subplots(figsize=fig_size) image = ax.imshow(data, vmin=-100, vmax=0, cmap='inferno', extent=extent) ax.set_position(pos=[fig_x_off, fig_y_off, fig_x_scale, fig_y_scale]) ax.set_title('Spektrogramm vom ' + datetime.fromtimestamp(basetime).strftime('%Y-%m-%d')) xrange = extent[1] - extent[0] yrange = extent[2] - extent[3] ax.set_aspect((data.shape[0] / yrange) / (data.shape[1] / xrange)) ax.yaxis_date() ax.yaxis.set_major_locator(HourLocator(range(0, 25, 1))) ax.yaxis.set_minor_locator(MinuteLocator(range(0, 60, 20))) ax.yaxis.set_major_formatter(DateFormatter('%H:%M')) ax.yaxis.set_minor_formatter(DateFormatter('%M')) ax.xaxis.set_major_locator(MultipleLocator(1.0)) ax.set_xlabel('Frequenz [MHz]') ax_top = ax.twiny() ax_top.xaxis.set_major_locator(MultipleLocator(1.0)) ax_top.set_xlabel('Frequenz [MHz]') ax_top.set_xlim(ax.get_xlim()) ax_top.set_position(pos=[fig_x_off, fig_y_off, fig_x_scale, fig_y_scale]) cax = pp.axes([fig_x_scale+fig_x_off+0.02, fig_y_off, 0.03, fig_y_scale]) pp.colorbar(cax=cax, mappable=image) cax.set_title('dBm') pp.savefig(outname)