1f08c3bdfSopenharmony_ci#!/usr/bin/env python3
2f08c3bdfSopenharmony_ci
3f08c3bdfSopenharmony_ci#      Filename: ftqviz.py
4f08c3bdfSopenharmony_ci#        Author: Darren Hart <dvhltc@us.ibm.com>
5f08c3bdfSopenharmony_ci#   Description: Plot the time and frequency domain plots of a times and
6f08c3bdfSopenharmony_ci#                counts log file pair from the FTQ benchmark.
7f08c3bdfSopenharmony_ci# Prerequisites: numpy, scipy, and pylab packages.  For debian/ubuntu:
8f08c3bdfSopenharmony_ci#                o python-numeric
9f08c3bdfSopenharmony_ci#                o python-scipy
10f08c3bdfSopenharmony_ci#                o python-matplotlib
11f08c3bdfSopenharmony_ci#
12f08c3bdfSopenharmony_ci# This program is free software; you can redistribute it and/or modify
13f08c3bdfSopenharmony_ci# it under the terms of the GNU General Public License as published by
14f08c3bdfSopenharmony_ci# the Free Software Foundation; either version 2 of the License, or
15f08c3bdfSopenharmony_ci# (at your option) any later version.
16f08c3bdfSopenharmony_ci#
17f08c3bdfSopenharmony_ci# This program is distributed in the hope that it will be useful,
18f08c3bdfSopenharmony_ci# but WITHOUT ANY WARRANTY; without even the implied warranty of
19f08c3bdfSopenharmony_ci# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20f08c3bdfSopenharmony_ci# GNU General Public License for more details.
21f08c3bdfSopenharmony_ci#
22f08c3bdfSopenharmony_ci# Copyright (C) IBM Corporation, 2007
23f08c3bdfSopenharmony_ci#
24f08c3bdfSopenharmony_ci# 2007-Aug-30:  Initial version by Darren Hart <dvhltc@us.ibm.com>
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_cifrom numpy import *
28f08c3bdfSopenharmony_cifrom numpy.fft import *
29f08c3bdfSopenharmony_cifrom scipy import *
30f08c3bdfSopenharmony_cifrom pylab import *
31f08c3bdfSopenharmony_cifrom sys import *
32f08c3bdfSopenharmony_cifrom getopt import *
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_ciNS_PER_S  = 1000000000
35f08c3bdfSopenharmony_ciNS_PER_MS = 1000000
36f08c3bdfSopenharmony_ciNS_PER_US = 1000
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_cidef smooth(x, wlen):
39f08c3bdfSopenharmony_ci    if x.size < wlen:
40f08c3bdfSopenharmony_ci        raise ValueError("Input vector needs to be bigger than window size.")
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_ci    # reflect the signal to avoid transients... ?
43f08c3bdfSopenharmony_ci    s = r_[2*x[0]-x[wlen:1:-1], x, 2*x[-1]-x[-1:-wlen:-1]]
44f08c3bdfSopenharmony_ci    w = hamming(wlen)
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci    # generate the smoothed signal
47f08c3bdfSopenharmony_ci    y = convolve(w/w.sum(), s, mode='same')
48f08c3bdfSopenharmony_ci    # recenter the smoothed signal over the originals (slide along x)
49f08c3bdfSopenharmony_ci    y1 = y[wlen-1:-wlen+1]
50f08c3bdfSopenharmony_ci    return y1
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_cidef my_fft(x, sample_hz):
54f08c3bdfSopenharmony_ci    X = abs(fftshift(fft(x)))
55f08c3bdfSopenharmony_ci    freq = fftshift(fftfreq(len(x), 1.0/sample_hz))
56f08c3bdfSopenharmony_ci    return array([freq, abs(X)/len(x)])
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_cidef smooth_fft(timefile, countfile, sample_hz, wlen):
60f08c3bdfSopenharmony_ci    # The higher the sample_hz, the larger the required wlen (used to generate
61f08c3bdfSopenharmony_ci    # the hamming window).  It seems that each should be adjusted by roughly the
62f08c3bdfSopenharmony_ci    # same factor
63f08c3bdfSopenharmony_ci    ns_per_sample = NS_PER_S / sample_hz
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci    print("Interpolated Sample Rate: ", sample_hz, " HZ")
66f08c3bdfSopenharmony_ci    print("Hamming Window Length: ", wlen)
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci    t = fromfile(timefile, dtype=int64, sep='\n')
69f08c3bdfSopenharmony_ci    x = fromfile(countfile, dtype=int64, sep='\n')
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci    # interpolate the data to achieve a uniform sample rate for use in the fft
72f08c3bdfSopenharmony_ci    xi_len = (t[len(t)-1] - t[0])/ns_per_sample
73f08c3bdfSopenharmony_ci    xi = zeros(xi_len)
74f08c3bdfSopenharmony_ci    last_j = 0
75f08c3bdfSopenharmony_ci    for i in range(0, len(t)-1):
76f08c3bdfSopenharmony_ci        j = (t[i] - t[0])/ns_per_sample
77f08c3bdfSopenharmony_ci        xi[j] = x[i]
78f08c3bdfSopenharmony_ci        m = (xi[j]-xi[last_j])/(j-last_j)
79f08c3bdfSopenharmony_ci        for k in range(last_j + 1, j):
80f08c3bdfSopenharmony_ci            xi[k] = m * (k - last_j) + xi[last_j]
81f08c3bdfSopenharmony_ci        last_j = j
82f08c3bdfSopenharmony_ci
83f08c3bdfSopenharmony_ci    # smooth the signal (low pass filter)
84f08c3bdfSopenharmony_ci    try:
85f08c3bdfSopenharmony_ci        y = smooth(xi, wlen)
86f08c3bdfSopenharmony_ci    except ValueError as e:
87f08c3bdfSopenharmony_ci        exit(e)
88f08c3bdfSopenharmony_ci
89f08c3bdfSopenharmony_ci    # generate the fft
90f08c3bdfSopenharmony_ci    X = my_fft(xi, sample_hz)
91f08c3bdfSopenharmony_ci    Y = my_fft(y, sample_hz)
92f08c3bdfSopenharmony_ci
93f08c3bdfSopenharmony_ci    # plot the hamming window
94f08c3bdfSopenharmony_ci    subplot(311)
95f08c3bdfSopenharmony_ci    plot(hamming(wlen))
96f08c3bdfSopenharmony_ci    axis([0,wlen-1,0,1.1])
97f08c3bdfSopenharmony_ci    title(str(wlen)+" Point Hamming Window")
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ci    # plot the signals
100f08c3bdfSopenharmony_ci    subplot(312)
101f08c3bdfSopenharmony_ci    ts = arange(0, len(xi), dtype=float)/sample_hz # time signal in units of seconds
102f08c3bdfSopenharmony_ci    plot(ts, xi, alpha=0.2)
103f08c3bdfSopenharmony_ci    plot(ts, y)
104f08c3bdfSopenharmony_ci    legend(['interpolated', 'smoothed'])
105f08c3bdfSopenharmony_ci    title("Counts (interpolated sample rate: "+str(sample_hz)+" HZ)")
106f08c3bdfSopenharmony_ci    xlabel("Time (s)")
107f08c3bdfSopenharmony_ci    ylabel("Units of Work")
108f08c3bdfSopenharmony_ci
109f08c3bdfSopenharmony_ci    # plot the fft
110f08c3bdfSopenharmony_ci    subplot(313)
111f08c3bdfSopenharmony_ci    plot(X[0], X[1], ls='steps', alpha=0.2)
112f08c3bdfSopenharmony_ci    plot(Y[0], Y[1], ls='steps')
113f08c3bdfSopenharmony_ci    ylim(ymax=20)
114f08c3bdfSopenharmony_ci    xlim(xmin=-3000, xmax=3000)
115f08c3bdfSopenharmony_ci    legend(['interpolated', 'smoothed'])
116f08c3bdfSopenharmony_ci    title("FFT")
117f08c3bdfSopenharmony_ci    xlabel("Frequency")
118f08c3bdfSopenharmony_ci    ylabel("Amplitude")
119f08c3bdfSopenharmony_ci
120f08c3bdfSopenharmony_ci    show()
121f08c3bdfSopenharmony_ci
122f08c3bdfSopenharmony_ci
123f08c3bdfSopenharmony_cidef usage():
124f08c3bdfSopenharmony_ci        print("usage: "+argv[0]+" -t times-file -c counts-file [-s SAMPLING_HZ] [-w WINDOW_LEN] [-h]")
125f08c3bdfSopenharmony_ci
126f08c3bdfSopenharmony_ci
127f08c3bdfSopenharmony_ciif __name__=='__main__':
128f08c3bdfSopenharmony_ci
129f08c3bdfSopenharmony_ci    try:
130f08c3bdfSopenharmony_ci        opts, args = getopt(argv[1:], "c:hs:t:w:")
131f08c3bdfSopenharmony_ci    except GetoptError:
132f08c3bdfSopenharmony_ci        usage()
133f08c3bdfSopenharmony_ci        exit(2)
134f08c3bdfSopenharmony_ci
135f08c3bdfSopenharmony_ci    sample_hz = 10000
136f08c3bdfSopenharmony_ci    wlen = 25
137f08c3bdfSopenharmony_ci    times_file = None
138f08c3bdfSopenharmony_ci    counts_file = None
139f08c3bdfSopenharmony_ci    for o, a in opts:
140f08c3bdfSopenharmony_ci        if o == "-c":
141f08c3bdfSopenharmony_ci            counts_file = a
142f08c3bdfSopenharmony_ci        if o == "-h":
143f08c3bdfSopenharmony_ci            usage()
144f08c3bdfSopenharmony_ci            exit()
145f08c3bdfSopenharmony_ci        if o == "-s":
146f08c3bdfSopenharmony_ci            sample_hz = int(a)
147f08c3bdfSopenharmony_ci        if o == "-t":
148f08c3bdfSopenharmony_ci            times_file = a
149f08c3bdfSopenharmony_ci        if o == "-w":
150f08c3bdfSopenharmony_ci            wlen = int(a)
151f08c3bdfSopenharmony_ci
152f08c3bdfSopenharmony_ci    if not times_file or not counts_file:
153f08c3bdfSopenharmony_ci        usage()
154f08c3bdfSopenharmony_ci        exit(1)
155f08c3bdfSopenharmony_ci
156f08c3bdfSopenharmony_ci    smooth_fft(times_file, counts_file, sample_hz, wlen)
157