mi@0
|
1 """
|
mi@0
|
2 Set of util functions for the section similarity project.
|
mi@0
|
3 """
|
mi@0
|
4
|
mi@0
|
5 import copy
|
mi@0
|
6 import numpy as np
|
mi@0
|
7 import json
|
mi@0
|
8 import scipy.fftpack
|
mi@0
|
9 import pylab as plt
|
mi@0
|
10
|
mi@0
|
11 def resample_mx(X, incolpos, outcolpos):
|
mi@0
|
12 """
|
mi@0
|
13 Y = resample_mx(X, incolpos, outcolpos)
|
mi@0
|
14 X is taken as a set of columns, each starting at 'time'
|
mi@0
|
15 colpos, and continuing until the start of the next column.
|
mi@0
|
16 Y is a similar matrix, with time boundaries defined by
|
mi@0
|
17 outcolpos. Each column of Y is a duration-weighted average of
|
mi@0
|
18 the overlapping columns of X.
|
mi@0
|
19 2010-04-14 Dan Ellis dpwe@ee.columbia.edu based on samplemx/beatavg
|
mi@0
|
20 -> python: TBM, 2011-11-05, TESTED
|
mi@0
|
21 """
|
mi@0
|
22 noutcols = len(outcolpos)
|
mi@0
|
23 Y = np.zeros((X.shape[0], noutcols))
|
mi@0
|
24 # assign 'end times' to final columns
|
mi@0
|
25 if outcolpos.max() > incolpos.max():
|
mi@0
|
26 incolpos = np.concatenate([incolpos,[outcolpos.max()]])
|
mi@0
|
27 X = np.concatenate([X, X[:,-1].reshape(X.shape[0],1)], axis=1)
|
mi@0
|
28 outcolpos = np.concatenate([outcolpos, [outcolpos[-1]]])
|
mi@0
|
29 # durations (default weights) of input columns)
|
mi@0
|
30 incoldurs = np.concatenate([np.diff(incolpos), [1]])
|
mi@0
|
31
|
mi@0
|
32 for c in range(noutcols):
|
mi@0
|
33 firstincol = np.where(incolpos <= outcolpos[c])[0][-1]
|
mi@0
|
34 firstincolnext = np.where(incolpos < outcolpos[c+1])[0][-1]
|
mi@0
|
35 lastincol = max(firstincol,firstincolnext)
|
mi@0
|
36 # default weights
|
mi@0
|
37 wts = copy.deepcopy(incoldurs[firstincol:lastincol+1])
|
mi@0
|
38 # now fix up by partial overlap at ends
|
mi@0
|
39 if len(wts) > 1:
|
mi@0
|
40 wts[0] = wts[0] - (outcolpos[c] - incolpos[firstincol])
|
mi@0
|
41 wts[-1] = wts[-1] - (incolpos[lastincol+1] - outcolpos[c+1])
|
mi@0
|
42 wts = wts * 1. /sum(wts)
|
mi@0
|
43 Y[:,c] = np.dot(X[:,firstincol:lastincol+1], wts)
|
mi@0
|
44 # done
|
mi@0
|
45 return Y
|
mi@0
|
46
|
mi@0
|
47 def magnitude(X):
|
mi@0
|
48 """Magnitude of a complex matrix."""
|
mi@0
|
49 r = np.real(X)
|
mi@0
|
50 i = np.imag(X)
|
mi@0
|
51 return np.sqrt(r * r + i * i);
|
mi@0
|
52
|
mi@0
|
53 def json_to_bounds(segments_json):
|
mi@0
|
54 """Extracts the boundaries from a json file and puts them into
|
mi@0
|
55 an np array."""
|
mi@0
|
56 f = open(segments_json)
|
mi@0
|
57 segments = json.load(f)["segments"]
|
mi@0
|
58 bounds = []
|
mi@0
|
59 for segment in segments:
|
mi@0
|
60 bounds.append(segment["start"])
|
mi@0
|
61 bounds.append(bounds[-1] + segments[-1]["duration"]) # Add last boundary
|
mi@0
|
62 f.close()
|
mi@0
|
63 return np.asarray(bounds)
|
mi@0
|
64
|
mi@0
|
65 def json_bounds_to_bounds(bounds_json):
|
mi@0
|
66 """Extracts the boundaries from a bounds json file and puts them into
|
mi@0
|
67 an np array."""
|
mi@0
|
68 f = open(bounds_json)
|
mi@0
|
69 segments = json.load(f)["bounds"]
|
mi@0
|
70 bounds = []
|
mi@0
|
71 for segment in segments:
|
mi@0
|
72 bounds.append(segment["start"])
|
mi@0
|
73 f.close()
|
mi@0
|
74 return np.asarray(bounds)
|
mi@0
|
75
|
mi@0
|
76 def json_to_labels(segments_json):
|
mi@0
|
77 """Extracts the labels from a json file and puts them into
|
mi@0
|
78 an np array."""
|
mi@0
|
79 f = open(segments_json)
|
mi@0
|
80 segments = json.load(f)["segments"]
|
mi@0
|
81 labels = []
|
mi@0
|
82 str_labels = []
|
mi@0
|
83 for segment in segments:
|
mi@0
|
84 if not segment["label"] in str_labels:
|
mi@0
|
85 str_labels.append(segment["label"])
|
mi@0
|
86 labels.append(len(str_labels)-1)
|
mi@0
|
87 else:
|
mi@0
|
88 label_idx = np.where(np.asarray(str_labels) == segment["label"])[0][0]
|
mi@0
|
89 labels.append(label_idx)
|
mi@0
|
90 f.close()
|
mi@0
|
91 return np.asarray(labels)
|
mi@0
|
92
|
mi@0
|
93 def json_to_beats(beats_json_file):
|
mi@0
|
94 """Extracts the beats from the beats_json_file and puts them into
|
mi@0
|
95 an np array."""
|
mi@0
|
96 f = open(beats_json_file, "r")
|
mi@0
|
97 beats_json = json.load(f)
|
mi@0
|
98 beats = []
|
mi@0
|
99 for beat in beats_json["beats"]:
|
mi@0
|
100 beats.append(beat["start"])
|
mi@0
|
101 f.close()
|
mi@0
|
102 return np.asarray(beats)
|
mi@0
|
103
|
mi@0
|
104 def analyze_results(file):
|
mi@0
|
105 f = open(file, "r")
|
mi@0
|
106 lines = f.readlines()
|
mi@0
|
107 F = []
|
mi@0
|
108 for line in lines:
|
mi@0
|
109 F.append(float(line.split("\t")[0]))
|
mi@0
|
110 f.close()
|
mi@0
|
111 print np.mean(F)
|
mi@0
|
112
|
mi@0
|
113 def compute_ffmc2d(X):
|
mi@0
|
114 """Computes the 2D-Fourier Magnitude Coefficients."""
|
mi@0
|
115 # 2d-fft
|
mi@0
|
116 fft2 = scipy.fftpack.fft2(X)
|
mi@0
|
117
|
mi@0
|
118 # Magnitude
|
mi@0
|
119 fft2m = magnitude(fft2)
|
mi@0
|
120
|
mi@0
|
121 # FFTshift and flatten
|
mi@0
|
122 fftshift = scipy.fftpack.fftshift(fft2m).flatten()
|
mi@0
|
123
|
mi@0
|
124 #cmap = plt.cm.get_cmap('hot')
|
mi@0
|
125 #plt.imshow(np.log1p(scipy.fftpack.fftshift(fft2m)).T, interpolation="nearest",
|
mi@0
|
126 # aspect="auto", cmap=cmap)
|
mi@0
|
127 #plt.show()
|
mi@0
|
128
|
mi@0
|
129 # Take out redundant components
|
mi@0
|
130 return fftshift[:fftshift.shape[0]/2+1]
|