changeset 17:c01fcb752221

new annotations
author mitian
date Fri, 21 Aug 2015 10:15:29 +0100
parents 8b814fe5781d
children b4bf37f94e92
files HSeg.py annotation/qupujicheng_annotation_30_3/10hongniang01.csv annotation/qupujicheng_annotation_30_3/10hongniang02.csv annotation/qupujicheng_annotation_30_3/10hongniang04.csv annotation/qupujicheng_annotation_30_3/1bawangbieji02.csv annotation/qupujicheng_annotation_30_3/1yuzhoufeng01.csv annotation/qupujicheng_annotation_30_3/1yuzhoufeng02.csv annotation/qupujicheng_annotation_30_3/2kongchengji_xipimanban.csv annotation/qupujicheng_annotation_30_3/2lilingbei.csv annotation/qupujicheng_annotation_30_3/2wenzhaoguan.csv annotation/qupujicheng_annotation_30_3/2xucepaocheng.csv annotation/qupujicheng_annotation_30_3/3dayushajia_xipikuaisanyan.csv annotation/qupujicheng_annotation_30_3/3nuqijie0215-0517.csv annotation/qupujicheng_annotation_30_3/4qingguance.csv annotation/qupujicheng_annotation_30_3/4yaoqi.csv annotation/qupujicheng_annotation_30_3/5suolinnang.csv annotation/qupujicheng_annotation_30_3/6liuyuexue.csv annotation/qupujicheng_annotation_30_3/6zhuofangcao_erhuangmanbanyuanban.csv annotation/qupujicheng_annotation_30_3/6zhuofangcao_xipimanban.csv annotation/qupujicheng_annotation_30_3/7jinyunu01.csv annotation/qupujicheng_annotation_30_3/7jinyunu04.csv annotation/qupujicheng_annotation_30_3/7jinyunu06.csv annotation/qupujicheng_annotation_30_3/7longfengchengxiang.csv annotation/qupujicheng_annotation_30_3/7sangyuanjizi.csv annotation/qupujicheng_annotation_30_3/8zuozhaidaoma01.csv annotation/qupujicheng_annotation_30_3/8zuozhaidaoma02.csv annotation/qupujicheng_annotation_30_3/9shangtiantai_erhaungkuaisanyan.csv annotation/qupujicheng_annotation_30_3/9shangtiantai_erhuangsanyan.csv annotation/qupujicheng_annotation_30_3/9shangtiantai_erhuangyuanban.csv annotation/qupujicheng_annotation_30_3/9tiannusanhua01.csv annotation/qupujicheng_annotation_30_3/9tiannusanhua02.csv cnmf.py novelty.py utils/SegUtil.py
diffstat 34 files changed, 1958 insertions(+), 128 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HSeg.py	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,456 @@
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+HSeg.py
+
+Created by mi tian on 2015-08-14.
+Copyright (c) 2015 __MyCompanyName__. All rights reserved.
+"""
+
+import sys, os, optparse, csv
+from itertools import combinations
+from os.path import join, isdir, isfile, abspath, dirname, basename, split, splitext
+from copy import copy
+
+import matplotlib
+matplotlib.use('Agg')
+import matplotlib.pyplot as plt
+import matplotlib.gridspec as gridspec
+import numpy as np
+import scipy as sp
+from scipy.signal import correlate2d, convolve2d, filtfilt, resample
+from scipy.ndimage.filters import *
+from scipy.ndimage.interpolation import zoom
+from sklearn.decomposition import PCA
+from sklearn.mixture import GMM
+from sklearn.cluster import KMeans
+from sklearn.preprocessing import normalize
+from sklearn.metrics.pairwise import pairwise_distances
+
+# Load dependencies
+from utils.SegUtil import getMean, getStd, getDelta, getSSM, reduceSSM, upSample, normaliseFeature, normaliseArray
+from utils.PeakPickerUtil import PeakPicker
+from utils.gmmdist import *
+from utils.GmmMetrics import GmmDistance
+from utils.RankClustering import rClustering
+from utils.kmeans import Kmeans
+
+# Using the novelty based (Tian) boundary retrieval method
+import novelty as novelty_S
+import sf as sf_S
+import cnmf as cnmf_S
+
+# Algorithm params
+h = 8               # Size of median filter for features in C-NMF
+R = 15              # Size of the median filter for the activation matrix C-NMF
+rank = 4            # Rank of decomposition for the boundaries
+rank_labels = 6     # Rank of decomposition for the labels
+R_labels = 6        # Size of the median filter for the labels
+# Foote
+M = 2           # Median filter for the audio features (in beats)
+Mg = 32         # Gaussian kernel size
+L = 16          # Size of the median filter for the adaptive threshold
+# 2D-FMC
+N = 8          # Size of the fixed length segments (for 2D-FMC)
+
+# Define arg parser
+def parse_args():
+	op = optparse.OptionParser()
+	# IO options
+	op.add_option('-f', '--features1', action="store", dest="F1", default='/Users/mitian/Documents/experiments/mit/features/gammatonegram_fft/qupujicheng/2048_1024', type="str", help="Loading features from.." )
+	op.add_option('-e', '--features2', action="store", dest="F2", default='/Users/mitian/Documents/experiments/mit/features/gammatonegram_fft/qupujicheng/2048_1024', type="str", help="Loading features from.." )
+	op.add_option('-a', '--annotations', action="store", dest="GT", default='/Volumes/c4dm-03/people/mit/annotation/qupujicheng/lowercase', type="str", help="Loading annotation files from.. ")
+	op.add_option('-d', '--dataset', action="store", dest="DATASET", default='qupujicheng', type="str", help="Specify datasets")
+	op.add_option('-o', '--output', action="store", dest="OUTPUT", default=' /Users/mitian/Documents/experiments/mit/gmm/gammatone_fft/qupujicheng', type="str", help="Loading annotation files from.. ")
+	op.add_option('-c', '--cache', action="store", dest="CACHE", default='/Users/mitian/Documents/experiments/mit/gmm/gammatone_fft/qupujicheng', type="str", help="Saving temporary cache files to.. ")
+	op.add_option('-n', '--name', action="store", dest="NAME", default=None, type="str", help="Save output under the name..")
+	
+	# Plot/print/mode options
+	op.add_option('-b', '--boundary-method', action="store_true", dest="BOUNDARY_ALL", default=False, help="Use all boundary method.")
+	op.add_option('-p', '--plot', action="store_true", dest="PLOT", default=False, help="Save plots")
+	op.add_option('-t', '--test-mode', action="store_true", dest="TEST", default=False, help="Test mode")
+	op.add_option('-v', '--verbose-mode', action="store_true", dest="VERBOSE", default=False, help="Print results in verbose mode.")
+
+	return op.parse_args()
+options, args = parse_args()
+
+class AudioObj():
+	__slots__ = ['name', 'feature_list', 'gt', 'label', 'features1', 'features2', 'ssm_timestamps']
+
+class EvalObj():
+	__slots__ = ['TP', 'FP', 'FN', 'P', 'R', 'F', 'AD', 'DA', 'detection']
+
+
+class Seg(object):
+	'''The main segmentation object'''
+	def __init__(self):
+		self.SampleRate = 44100
+		self.NqHz = self.SampleRate/2
+		self.timestamp = []
+		self.previousSample = 0.0
+		self.featureWindow = 6.0
+		self.featureStep = 3.0
+		self.kernel_size = 100 # Adjust this param according to the feature resolution.pq
+		self.blockSize = 2048
+		self.stepSize = 1024
+
+		'''NOTE: Match the following params with those used for feature extraction!'''
+		
+		'''NOTE: Unlike spectrogram ones, Gammatone features are extracted without taking an FFT. The windowing is done under the purpose of chunking
+		the audio to facilitate the gammatone filtering with the specified blockSize and stepSize. The resulting gammatonegram is aggregated every
+		gammatoneLen without overlap.'''
+		self.gammatoneLen = 2048
+		self.gammatoneBandGroups = [0, 2, 6, 10, 13, 17, 20]
+		self.nGammatoneBands = 20
+		self.lowFreq = 100
+		self.highFreq = self.SampleRate / 4
+		
+		'''Settings for extracting tempogram features.'''
+		self.tempoWindow = 6.0
+		self.bpmBands = [30, 45, 60, 80, 100, 120, 180, 240, 400, 600]
+		
+		'''Peak picking settings for novelty based method'''
+		self.threshold = 30
+		self.confidence_threshold = 0.5
+		self.delta_threshold = 0.0
+		self.backtracking_threshold = 1.9
+		self.polyfitting_on = True
+		self.medfilter_on = True
+		self.LPfilter_on = True
+		self.whitening_on = False
+		self.aCoeffs = [1.0000, -0.5949, 0.2348]
+		self.bCoeffs = [0.1600,	 0.3200, 0.1600]
+		self.cutoff = 0.34
+		self.medianWin = 7
+				
+			
+	def pairwiseF(self, annotation, detection, tolerance=3.0, combine=1.0, idx2time=None):
+		'''Pairwise F measure evaluation of detection rates.'''
+		
+		res = EvalObj()
+		res.TP, res.FP, res.FN = 0, 0, 0	
+		res.P, res.R, res.F = 0.0, 0.0, 0.0
+		res.AD, res.DA = 0.0, 0.0
+		
+		if len(detection) == 0:
+			return res
+	
+		if idx2time != None:
+			# Map detected idxs to real time
+			detection.sort()
+			if detection[-1] >= len(idx2time): 
+				detection = detection[:-len(np.array(detection)[np.array(detection)-len(idx2time)>0])]
+			detection = [idx2time[int(i)] for i in detection]
+		detection = np.append(detection, annotation[-1])
+		res.detection = detection
+	
+		gt = len(annotation)	# Total number of ground truth data points
+		dt = len(detection) # Total number of experimental data points
+		foundIdx = []	
+		D_AD = np.zeros(gt)
+		D_DA = np.zeros(dt)
+		
+		for dtIdx in xrange(dt):
+			D_DA[dtIdx] = np.min(abs(detection[dtIdx] - annotation))
+		
+		for gtIdx in xrange(gt):
+			D_AD[gtIdx] = np.min(abs(annotation[gtIdx] - detection))
+			for dtIdx in xrange(dt):
+				if (annotation[gtIdx] >= detection[dtIdx] - tolerance/2.0) and (annotation[gtIdx] <= detection[dtIdx] + tolerance/2.0):
+					foundIdx.append(gtIdx)
+					continue
+		foundIdx = list(set(foundIdx))		
+		res.TP = len(foundIdx)
+		# res.FP = dt - res.TP
+		res.FP = max(0, dt - res.TP)	
+		res.FN = gt - res.TP
+
+		res.AD = np.mean(D_AD)		
+		res.DA = np.mean(D_DA)	
+		
+		if res.TP == 0:
+			return res
+
+		res.P = res.TP / float(res.TP+res.FP)
+		res.R = res.TP / float(res.TP+res.FN)
+		res.F = 2 * res.P * res.R / (res.P + res.R)
+		return res
+			
+	def writeVerifiedHeader(self, filename):
+		'''Write header of output files for verified segmentation.'''
+		
+		with open(filename, 'a') as f:
+			csvwriter = csv.writer(f, delimiter=',')
+			csvwriter.writerow(['audio', 'novelty_05_TP', 'novelty_05_FP', 'novelty_05_FN', 'novelty_05_P', 'novelty_05_R', 'novelty_05_F', 'novelty_05_AD', 'novelty_05_DA', 'novelty_3_TP', 'novelty_3_FP', 'novelty_3_FN', 'novelty_3_P', 'novelty_3_R', 'novelty_3_F', 'novelty_3_AD', 'novelty_3_DA',\
+			 'verified_novelty_05_TP', 'verified_novelty_05_FP', 'verified_novelty_05_FN', 'verified_novelty_05_P', 'verified_novelty_05_R', 'verified_novelty_05_F', 'verified_novelty_05_AD', 'verified_novelty_05_DA', 'verified_novelty_3_TP', 'verified_novelty_3_FP',\
+			 'gt_verified_3_FN'])
+		
+	def writeVerifiedRes(self, filename, ao_name, novelty_05, novelty_3, verified_novelty_05, verified_novelty_3):
+		'''Write result of single detection for verified segmentation.'''
+		
+		with open(filename, 'a') as f:
+			csvwriter = csv.writer(f, delimiter=',')
+			csvwriter.writerow([ao_name, novelty_05.TP, novelty_05.FP, novelty_05.FN, novelty_05.P, novelty_05.R, novelty_05.F, novelty_05.AD, novelty_05.DA, novelty_3.TP, novelty_3.FP, novelty_3.FN, novelty_3.P, novelty_3.R,\
+			novelty_3.F, novelty_3.AD, novelty_3.DA, verified_novelty_05.TP, verified_novelty_05.FP, verified_novelty_05.FN, verified_novelty_05.P, verified_novelty_05.R, verified_novelty_05.F, verified_novelty_05.AD, verified_novelty_05.DA,
+			verified_novelty_3.TP, verified_novelty_3.FP, verified_novelty_3.FN, verified_novelty_3.P, verified_novelty_3.R, verified_novelty_3.F, verified_novelty_3.AD, verified_novelty_3.DA])
+	
+	def localBoundaries(self, bound_idx, feature, confidence, peak_picker, thresh=0.3, tol=3, metric='novelty'):
+		'''Detect local bounderies within fixed-len window around a boudary from the first round detection.
+		args: bound_idx: index of boundary condidate for local inspection
+			  feature: an alternative feature for local pairwise distance measuring
+			  confidence: a list of confidence values assigned to all boundary candidates.
+			  thresh: threshold for boundary confidence
+			  tol: window length (L = 2*tol + 1) for extracting local features (unit=s)	
+			  metric: 'novelty' (default), 'sf', 'cnmf'
+		'''
+		
+		local_boundaries = []
+		smoothed_local_novelty = None
+		
+		tol_win = float(tol) / self.stepSize * self.SampleRate
+		
+		if confidence[bound_idx] < thresh:
+			return local_boundaries, smoothed_local_novelty
+		# print 'bound_idx', bound_idx, len(confidence), feature.shape
+		
+		# If the boundary is of high relative confidence, keep it anyway	
+		if (1 < bound_idx < len(confidence)-1):
+			if confidence[bound_idx-1] / thresh <= confidence[bound_idx] and confidence[bound_idx-1] / thresh <= confidence[bound_idx]:
+				local_boundaries.append(bound_idx)
+		pre_win = np.max([int(bound_idx-tol_win), 0])
+		post_win = np.min([int(bound_idx+tol_win), len(confidence)])
+		
+		local_feature = feature[pre_win: post_win, :]
+		local_ssm = pairwise_distances(local_feature, metric='cosine')
+
+		if metric == 'novelty': local_novelty, smoothed_local_novelty, local_idxs = novelty_S.process(local_ssm, peak_picker, 48)
+		elif metric == 'sf': nc, local_idxs = sf_S.segmentation(local_ssm)
+		elif metric == 'cnmf': G, local_idxs = cnmf_S.segmentation(local_ssm)
+
+		if local_idxs: local_idxs += map(lambda x: x+bound_idx, local_idxs)
+		# print local_idxs
+
+		return list(set(local_idxs)), smoothed_local_novelty
+		
+	def verifyPeaks(self, bound_idx, second_detection, thresh=0.6, tol = 3, second_detection_conf=None):
+		'''Pruning second round detection.
+		args: bound_idx: index of boundary condidate for local inspection 
+			  second_detection: a list of peaks detected in the second round near a boudary candidates. 
+			  thresh: confidence threshold for discarding detection
+			  second_detection_conf: a list of confidence values assigned to all local peaks.
+		'''
+		
+		tol_win = float(tol) / self.stepSize * self.SampleRate
+		
+		# Select peak with the highest local confidence
+		if second_detection_conf:
+			if np.max(second_detection_conf) > thresh:
+				verified = bound_idx + np.argmax(second_detection_conf) - tol_win
+				return verified
+			else:
+				 return None
+				
+		# Select peak closest to the 1st round detection
+		elif second_detection:		
+			# pos = np.argmin(abs(np.array(second_detection)-bound_idx))
+			pos = int(np.mean(np.where(abs(np.array(second_detection)-bound_idx) == abs(np.array(second_detection)-bound_idx).min())[0]))
+			verified_peak = second_detection[pos]
+			return verified_peak
+			
+		# No peak is secured around bound_idx in the second round verification 
+		else:
+			return None
+			
+	def secondRoundDetection(self, peak_candidates, candidates_conf, feature, peak_verifier=None, tol=3, thresh=0.5):
+		'''Second round detection.'''
+		
+		peaks = []
+		
+		tol_win = float(tol) / self.stepSize * self.SampleRate
+		for i, x in enumerate(peak_candidates):
+			# bypass peak candidates with low confidence
+			if candidates_conf[x] < thresh: continue
+			
+			pre_win = np.max([int(x-tol_win), 0])
+			post_win = np.min([int(x+tol_win), len(candidates_conf)])
+			if pre_win == post_win: continue
+			
+			local_feature = feature[pre_win: post_win, :]
+			local_ssm = pairwise_distances(local_feature, metric='cosine')
+
+			local_conf, local_peaks = novelty_S.process(local_ssm,peak_verifier,int(120))[-2:]
+			if len(local_peaks)==0: 
+				continue
+			
+			local_conf = normaliseArray(local_conf)			
+			
+			# Keep the one detected from the 2nd around with the highest confidence as final peak
+			if np.max(local_conf[local_peaks]) > thresh:
+				local_bound = x - tol_win + np.argmax(local_conf)
+				peaks.append(np.rint(local_bound))
+				
+			peaks.sort()
+		return peaks
+			
+	def process(self):
+		'''Load precomputed features for all audio samples and make segmentation calls.'''
+		
+		# peak_picker for the 1st round boudary detection
+		peak_picker = PeakPicker()
+		peak_picker.params.alpha = 9.0 # Alpha norm
+		peak_picker.params.delta = self.delta_threshold # Adaptive thresholding delta
+		peak_picker.params.QuadThresh_a = (100 - self.threshold) / 1000.0
+		peak_picker.params.QuadThresh_b = 0.0
+		peak_picker.params.QuadThresh_c = (100 - self.threshold) / 1500.0
+		peak_picker.params.rawSensitivity = 20
+		peak_picker.params.aCoeffs = self.aCoeffs 
+		peak_picker.params.bCoeffs = self.bCoeffs
+		peak_picker.params.preWin = self.medianWin
+		peak_picker.params.postWin = self.medianWin + 1
+		peak_picker.params.LP_on = self.LPfilter_on
+		peak_picker.params.Medfilt_on = self.medfilter_on
+		peak_picker.params.Polyfit_on = self.polyfitting_on		
+		peak_picker.params.isMedianPositive = False
+
+		# peak_picker for the second round boudary verification (might need lower sensitivity)
+		peak_verifier = PeakPicker()
+		peak_verifier.params.alpha = 9.0 # Alpha norm
+		peak_verifier.params.delta = self.delta_threshold # Adaptive thresholding delta
+		peak_verifier.params.QuadThresh_a = (100 - 50) / 1000.0
+		peak_verifier.params.QuadThresh_b = 0.0
+		peak_verifier.params.QuadThresh_c = (100 - 50) / 1500.0
+		peak_verifier.params.rawSensitivity = 30
+		peak_verifier.params.aCoeffs = self.aCoeffs 
+		peak_verifier.params.bCoeffs = self.bCoeffs
+		peak_verifier.params.preWin = 10
+		peak_verifier.params.postWin = 10 + 1
+		peak_verifier.params.LP_on = self.LPfilter_on
+		peak_verifier.params.Medfilt_on = self.medfilter_on
+		peak_verifier.params.Polyfit_on = self.polyfitting_on		
+		peak_verifier.params.isMedianPositive = False
+
+		# Getting aggregated features.
+		featureRate = float(self.SampleRate) / self.stepSize
+		aggregation_window, aggregation_step = 20, 10
+		
+		audio_files = [x for x in os.listdir(options.GT) if not x.startswith(".") ]
+		audio_files.sort()
+		if options.TEST:
+			audio_files = audio_files[5:6]
+		audio_list = []
+		
+		# Use mfccs feature 1st round segmentation (coarse)
+		feature_list1 = ['mfcc_harmonic']
+		feature_list1 = [join(options.F1, f) for f in feature_list1]
+		feature_list2 = ['dct']
+		feature_list2 = [join(options.F2, f) for f in feature_list2]
+
+		# Prepare output files.
+		outfile1 = join(options.OUTPUT, 'verified_novelty.csv')
+		self.writeVerifiedHeader(outfile1)
+		
+		# For each audio file, load specific features
+		for audio in audio_files:
+			ao = AudioObj()
+			ao.name = splitext(audio)[0]
+
+			# Load annotations for specified audio collection.
+			if options.DATASET == 'qupujicheng':
+				annotation_file = join(options.GT, ao.name+'.csv') # qupujicheng
+				ao.gt = np.genfromtxt(annotation_file, usecols=0, delimiter=',')	
+				ao.label = np.genfromtxt(annotation_file, usecols=1, delimiter=',', dtype=str)
+			elif options.DATASET == 'salami':	
+				annotation_file = join(options.GT, ao.name+'.txt') # iso, salami
+				ao.gt = np.genfromtxt(annotation_file, usecols=0)	
+				ao.label = np.genfromtxt(annotation_file, usecols=1, dtype=str)
+			else:
+				annotation_file = join(options.GT, ao.name+'.lab') # beatles
+				ao.gt = np.genfromtxt(annotation_file, usecols=(0,1))
+				ao.gt = np.unique(np.ndarray.flatten(ao.gt))
+				ao.label = np.genfromtxt(annotation_file, usecols=2, dtype=str)
+			
+			featureset1, featureset2 = [], []
+			# Features for 1st round segmentation
+			for feature in feature_list1:
+				for f in os.listdir(feature):
+					if f[:f.find('_vamp')]==ao.name: 
+						featureset1.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
+						break
+			if len(feature_list1) > 1:
+				n_frame = np.min([x.shape[0] for x in featureset1])
+				featureset1 = [x[:n_frame,:] for x in featureset1]
+				ao.features1 = np.hstack((featureset1))
+			else:
+				ao.features1 = featureset1[0]
+
+			ao.ssm_timestamps = np.arange(0, ao.gt[-1], float(self.stepSize)/self.SampleRate)	
+			
+			# Features for 2nd round verification
+			for feature in feature_list2:
+				for f in os.listdir(feature):
+					if f[:f.find('_vamp')]==ao.name: 
+						featureset2.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
+						break
+			if len(feature_list2) > 1:
+				n_frame = np.min([x.shape[0] for x in featureset2])
+				featureset2 = [x[:n_frame,:] for x in featureset2]
+				ao.features2 = np.hstack((featureset2))
+			else:
+				ao.features2 = featureset2[0]
+
+			
+			pca = PCA(n_components=6)
+			
+			# Normalise features. 
+			# Note that tempogram features are extracted from a different stepsize as the others.
+			step = ao.features1.shape[0] / aggregation_step
+			ao.features1 = resample(ao.features1, step)
+			ao.features1 = normaliseFeature(ao.features1)
+						
+			pca.fit(ao.features1)
+			ao.features1 = pca.transform(ao.features1)
+			ssm1 = getSSM(ao.features1)
+				
+			ssm1_timestamps = ao.ssm_timestamps[::aggregation_step]
+			# Take care with this! It gains memory pressure when processing large dataset.
+			# audio_list.append(ao)
+			
+			# Segment the music at a coarse scale
+			# Within the neighborhood of each peak candidate, verify the boundary location at a finer scale.
+			novelty, smoothed_novelty, novelty_idxs = novelty_S.process(ssm1, peak_picker, self.kernel_size)
+				
+			novelty_05 = self.pairwiseF(ao.gt, novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ssm1_timestamps)
+			novelty_3 = self.pairwiseF(ao.gt, novelty_idxs, tolerance=3, combine=1.0, idx2time=ssm1_timestamps)
+			
+			# Verification using different features at a finer scale.
+			# Map to the orginal time scale
+			peak_candidates = np.array(map(lambda x: int(np.rint(x*aggregation_step)), novelty_idxs))
+			
+			peak_conf = normaliseArray(smoothed_novelty)			
+			if options.VERBOSE:	
+				np.savetxt(join(options.CACHE, ao.name+'-sn-raw.txt'), np.array(zip(ssm1_timestamps, peak_conf)), delimiter=',')
+			peak_conf = zoom(peak_conf, aggregation_step)
+			peak_candidates = peak_candidates[:len(peak_conf)]
+			
+			verified_novelty_idxs = self.secondRoundDetection(peak_candidates, peak_conf, ao.features2, peak_verifier, tol=1, thresh=0.4)
+			verified_novelty_idxs = list(set(verified_novelty_idxs))
+			
+ 			verified_novelty_05 = self.pairwiseF(ao.gt, verified_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			verified_novelty_3 = self.pairwiseF(ao.gt, verified_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)				
+				
+			# Write results.
+			self.writeVerifiedRes(outfile1, ao.name, novelty_05, novelty_3, verified_novelty_05, verified_novelty_3)
+			
+			if options.VERBOSE:	
+				print ao.name, novelty_3.TP, novelty_3.FP, novelty_3.FN, novelty_3.P, novelty_3.R, novelty_3.F, verified_novelty_3.TP, verified_novelty_3.FP, verified_novelty_3.FN,  verified_novelty_3.P, verified_novelty_3.R, verified_novelty_3.F
+				np.savetxt(join(options.CACHE, ao.name+'-raw.txt'), novelty_3.detection, delimiter=',')
+				np.savetxt(join(options.CACHE, ao.name+'-verified.txt'), verified_novelty_3.detection, delimiter=',')
+				
+def main():
+	segmenter = Seg()
+	segmenter.process()
+
+
+if __name__ == '__main__':
+	main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/10hongniang01.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,29 @@
+0.000000000,sp
+13.526553287,1.3
+19.257142857,a
+32.538775510,New Point
+50.710204081,New Point
+65.763265306,New Point
+70.141678004,New Point
+87.098049886,sp
+96.361405895,1.4
+110.155464852,sp
+113.795192743,New Point
+140.294965986,s
+153.948299319,sp
+171.047278911,2.2
+180.258730158,2.3
+189.741859410,New Point
+198.693877551,New Point
+200.620408163,sp
+205.879727891,New Point
+214.250521541,New Point
+219.713015873,New Point
+234.736326530,New Point
+244.802176870,New Point
+251.123809523,a
+258.979591836,New Point
+262.987755102,New Point
+272.764807256,New Point
+282.011111111,2.4
+287.091519274,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/10hongniang02.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,71 @@
+2.345215419
+7.035646258
+12.051156462
+14.117732426
+16.184308390
+19.202902494
+21.060498866
+26.238548752
+31.091519274
+35.990929705
+41.331519274
+44.651972789
+46.672108843
+48.878004535
+57.004988662
+58.746485260
+63.692335600
+64.249614512
+69.636643990
+71.912199546
+74.930793650
+80.132063492
+91.672380952
+95.248253968
+97.407709750
+104.002176870
+106.718911564
+112.152380952
+115.170975056
+120.674104308
+126.014693877
+134.745396825
+136.370793650
+139.110748299
+141.641723356
+144.869297052
+153.251700680
+159.033469387
+162.980861678
+167.857052154
+171.734784580
+176.866394557
+180.790566893
+185.829297052
+192.957823129
+199.296870748
+203.708662131
+206.657596371
+212.230385487
+218.337233560
+219.962630385
+221.982766439
+227.067936507
+230.109750566
+234.591201814
+244.900861678
+246.874557823
+250.938049886
+253.886984126
+257.741496598
+261.247709750
+265.961360544
+266.495419501
+269.281814058
+275.899501133
+280.032653061
+287.184399092
+293.268027210
+298.608616780
+303.949206349
+304.274285714
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/10hongniang04.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,66 @@
+0.000000000,1.1
+3.784852607,New Point
+8.685714285,s
+25.070045351,1.1
+44.179591836,a
+58.530612244,p
+61.091700680,s
+71.569705215,New Point
+84.045396825,1.1
+87.534693877,New Point
+118.170068027,sp
+123.119002267,1.2
+136.695873015,sp
+140.678095238,New Point
+151.812063492,New Point
+174.624013605,1.3
+193.581247165,1.4
+202.895963718,New Point
+206.065487528,New Point
+211.417687074,New Point
+214.436281179,New Point
+226.530045351,2.1
+235.575510204,New Point
+241.230566893,a
+261.748231292,2.2
+277.648979591,New Point
+293.110204081,New Point
+300.005011337,2.2
+302.521179138,New Point
+315.183673469,New Point
+327.424580498,New Point
+336.882562358,2.3
+345.616326530,New Point
+352.160272108,2.3
+379.674376417,2.4
+392.820317460,3.1
+425.993287981,New Point
+430.230929705,sp
+482.510657596,New Point
+486.922448979,New Point
+494.445714285,New Point
+503.977324263,2.4
+527.510929705,a
+539.077551020,New Point
+548.220408163,New Point
+563.629569160,New Point
+578.259387755,4.1
+586.378344671,1.2
+592.689455782,4.2
+600.793106575,New Point
+609.442539682,New Point
+616.183356009,4.3
+631.351655328,4.4
+637.065714285,3.2
+648.985782312,3.3
+656.242358276,a
+679.330612244,New Point
+688.400000000,New Point
+696.496258503,4.1
+703.901315192,New Point
+715.796802721,4.2
+733.089795918,New Point
+742.755396825,5.1
+747.424195011,5.2
+753.179183673,5.3
+758.944217687,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/1bawangbieji02.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,21 @@
+0.285170068,s
+10.762448979,New Point
+18.982312925,New Point
+32.449886621,New Point
+39.787755102,a
+51.362539682,s
+58.165986394,New Point
+77.453061224,New Point
+82.220408163,New Point
+87.183673469,a
+123.771428571,a
+140.114285714,New Point
+147.073469387,a
+156.595374149,New Point
+165.535056689,New Point
+186.224036281,New Point
+195.330612244,New Point
+205.403718820,New Point
+216.783673469,New Point
+256.946938775,New Point
+256.975238095,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/1yuzhoufeng01.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,20 @@
+0.000000000,s
+1.502040816,New Point
+13.630113378,New Point
+24.171972789,a
+35.918367346,New Point
+40.930612244,New Point
+51.501859410,New Point
+62.682267573,New Point
+73.932335600,a
+99.673469387,New Point
+117.516190476,a
+128.998458049,New Point
+137.240816326,New Point
+157.651882086,New Point
+166.997913832,p
+175.891156462,New Point
+181.951564625,a
+193.942857142,New Point
+218.579591836,New Point
+224.153832199,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/1yuzhoufeng02.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,66 @@
+0.000000000,p
+1.486077097,New Point
+9.534421768,s
+14.466031746,New Point
+28.537324263,New Point
+34.644172335,New Point
+38.171428571,New Point
+41.918367346,New Point
+57.051428571,New Point
+76.776780045,New Point
+84.218775510,New Point
+87.477551020,New Point
+91.057052154,New Point
+94.458775510,a
+103.738775510,New Point
+137.289795918,New Point
+144.544217687,New Point
+149.257142857,New Point
+155.461224489,New Point
+159.053061224,New Point
+162.725442176,a
+179.461224489,New Point
+194.253061224,New Point
+209.374331065,New Point
+228.321814058,New Point
+235.102040816,New Point
+249.242993197,New Point
+252.400907029,New Point
+255.605260770,a
+268.963265306,New Point
+287.625578231,New Point
+290.667392290,New Point
+303.473197278,New Point
+308.941496598,New Point
+312.099410430,New Point
+315.605623582,a
+331.937437641,1.1
+347.493877551,New Point
+360.081632653,New Point
+369.893877551,New Point
+376.283174603,1.2
+408.000000000,New Point
+424.971609977,New Point
+442.155102040,New Point
+453.597959183,p
+462.077097505,s
+479.793922902,New Point
+485.668571428,a
+499.855963718,New Point
+513.834376417,New Point
+531.249342403,New Point
+540.281904761,New Point
+550.011065759,New Point
+565.928344671,New Point
+578.083990929,a
+585.077551020,New Point
+589.142857142,New Point
+603.457823129,s
+615.183673469,New Point
+620.390748299,a
+636.179591836,New Point
+651.820408163,New Point
+661.942857142,New Point
+669.844897959,New Point
+675.951020408,New Point
+682.248707482,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/2kongchengji_xipimanban.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,39 @@
+0.000000000,p
+10.777551020,s
+15.348390022,New Point
+24.491247165,New Point
+34.253061224,a
+45.056281179,1.3
+62.600997732,New Point
+71.331700680,New Point
+77.252789115,New Point
+79.560929705,1.3
+83.940136054,New Point
+94.025011337,1.4
+104.228571428,New Point
+120.685714285,a
+142.013242630,New Point
+155.069387755,New Point
+161.619818594,2.2
+173.627210884,a
+183.205442176,New Point
+194.840816326,New Point
+203.522902494,New Point
+207.278730158,New Point
+216.114285714,New Point
+234.080362811,New Point
+249.142857142,a
+262.553287981,s
+272.602267573,a
+280.589931972,New Point
+294.351972789,3.2
+297.877188208,New Point
+300.437188208,New Point
+307.014240362,a
+317.370340136,New Point
+341.484263038,s
+355.102766439,New Point
+358.817959183,s
+370.335056689,a
+383.547210884,p
+388.783673469,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/2lilingbei.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,78 @@
+0.000000000,p
+16.904126984,New Point
+21.923061224,1.2
+41.306122448,New Point
+58.775510204,a
+67.428571428,New Point
+78.334693877,s
+95.677823129,a
+112.326530612,New Point
+134.907936507,s
+152.253242630,a
+169.828571428,New Point
+187.689795918,New Point
+202.210975056,a
+219.275782312,s
+233.674013605,a
+243.853061224,New Point
+262.008163265,New Point
+270.907210884,New Point
+284.072925170,a
+299.820408163,New Point
+310.334693877,a
+331.766712018,New Point
+345.420408163,New Point
+356.702040816,a
+368.640000000,New Point
+382.579591836,a
+391.379591836,New Point
+401.551020408,New Point
+415.660408163,New Point
+427.572244897,New Point
+434.987755102,a
+455.256235827,New Point
+479.967346938,New Point
+488.245986394,New Point
+497.162448979,New Point
+511.976780045,New Point
+535.183673469,New Point
+546.099092970,1.2
+555.461224489,New Point
+560.522448979,New Point
+568.018140589,a
+587.522902494,a
+602.514285714,New Point
+609.959183673,New Point
+617.257142857,New Point
+632.016326530,New Point
+639.493877551,New Point
+646.987755102,New Point
+654.302040816,New Point
+661.559727891,New Point
+680.486281179,1.2
+693.828571428,New Point
+702.055328798,p
+710.236734693,New Point
+717.148299319,s
+723.498956916,a
+745.499863945,p+s
+752.372970521,a
+756.807981859,New Point
+763.135419501,New Point
+774.987755102,New Point
+780.897959183,New Point
+786.824489795,s
+793.600000000,a
+804.702040816,s
+810.310204081,a
+827.020408163,p
+835.244988662,New Point
+854.734693877,a
+875.369070294,New Point
+898.612244897,New Point
+928.391836734,New Point
+945.497959183,a
+971.710204081,p
+976.956371882,New Point
+984.200997732,New Point
+984.489795918,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/2wenzhaoguan.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,68 @@
+0.000000000,p
+2.514285714,s
+27.265306122,a
+36.455328798,New Point
+49.926530612,s
+61.061224489,a
+88.751020408,s
+109.093877551,New Point
+117.028571428,a
+135.778684807,New Point
+154.285714285,s
+164.081632653,a
+170.480907029,New Point
+180.604081632,s
+191.085714285,a
+201.084807256,New Point
+218.325623582,New Point
+235.102040816,New Point
+246.386938775,New Point
+252.191927437,New Point
+263.093696145,New Point
+269.026394557,New Point
+282.076009070,New Point
+293.518367346,New Point
+298.424489795,New Point
+312.912108843,New Point
+329.746575963,New Point
+347.338775510,New Point
+365.319546485,New Point
+384.114829931,1.1
+397.191836734,New Point
+416.866780045,1.2
+440.761179138,a
+454.204081632,New Point
+467.297959183,New Point
+472.464943310,1.4
+481.767619047,s
+491.624489795,New Point
+499.379591836,New Point
+513.697959183,New Point
+520.312743764,a
+528.530612244,New Point
+559.967346938,New Point
+567.281632653,New Point
+584.081632653,p
+595.313197278,s
+601.861224489,a
+607.159183673,New Point
+614.365170068,New Point
+626.546938775,New Point
+635.808798185,a
+643.632653061,New Point
+657.200000000,s+p
+663.836734693,a
+688.816326530,New Point
+703.289795918,p+s
+709.714285714,a
+716.685714285,New Point
+726.459501133,New Point
+733.007528344,New Point
+742.465306122,New Point
+753.453061224,New Point
+760.198095238,a
+773.746938775,New Point
+777.357641723,a
+788.506122448,New Point
+806.870204081,New Point
+806.987755102,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/2xucepaocheng.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,28 @@
+0.000000000,1.1
+6.130068027,New Point
+9.273469387,New Point
+14.895600907,s
+21.292698412,a
+25.877551020,New Point
+33.536553287,1.3
+47.200000000,New Point
+56.375510204,New Point
+69.543764172,New Point
+80.051247165,p
+91.216326530,New Point
+96.361541950,1.3
+115.774693877,New Point
+119.652426303,New Point
+128.940408163,s
+132.980680272,New Point
+142.203061224,1.4
+164.072199546,a
+169.946848072,New Point
+181.185306122,New Point
+188.544580498,New Point
+193.201632653,s
+209.600000000,New Point
+239.026213151,New Point
+250.311111111,New Point
+262.106122448,p
+268.167256235,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/3dayushajia_xipikuaisanyan.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,27 @@
+0.000000000,p
+7.453605442,s
+25.193650793,a
+32.600816326,New Point
+41.540498866,s
+47.113287981,New Point
+53.521995464,a
+60.348662131,New Point
+71.164512471,1.2
+78.661224489,a
+86.285351473,New Point
+98.689591836,1.3
+109.044897959,a
+115.058344671,1.4
+125.648662131,2.1
+142.823469387,2.4
+151.657142857,a
+157.384580498,3.1
+164.089795918,p+s
+176.783673469,a
+187.069387755,New Point
+204.939319727,New Point
+209.490430839,New Point
+212.694784580,New Point
+224.587755102,p
+228.437913832,New Point
+236.767346938,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/3nuqijie0215-0517.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,21 @@
+0.000000000,1.1
+3.947392290,sp+p
+10.851269841,1.2
+19.063582766,New Point
+23.428934240,New Point
+31.370158730,s+p
+43.026575963,New Point
+53.684535147,a
+71.916077097,1.4
+85.426213151,New Point
+94.053809523,3.1
+108.158548752,s+p
+113.545578231,New Point
+122.624580498,a
+131.357981859,2.4
+141.339863945,New Point
+147.957551020,p
+153.019501133,p+s+sp
+159.134693877,a
+176.241655328,3.2
+182.276643990,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/4qingguance.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,48 @@
+0.000000000,1.1
+8.974512471,sp
+38.796462585,1.2
+46.309546485,2.1
+61.942857142,a
+68.734693877,New Point
+79.738775510,New Point
+89.624376417,2.3
+112.616780045,New Point
+126.245351473,a
+136.231473922,New Point
+157.053718820,3.3
+166.090793650,a
+187.917551020,a
+197.230294784,New Point
+210.303129251,New Point
+219.451791383,New Point
+223.366757369,4.2
+244.807981859,a
+258.159455782,New Point
+277.362358276,New Point
+291.040907029,4.4
+311.635011337,a
+324.243446712,New Point
+342.656870748,New Point
+374.236009070,New Point
+378.947596371,5.3
+388.679795918,2.1
+400.587755102,a
+412.850793650,New Point
+430.846258503,New Point
+443.189954648,6.2
+456.736507936,New Point
+467.983673469,New Point
+485.528730158,6.3
+497.012244897,a
+508.733673469,6.4
+547.428571428,p+s 
+558.823038548,a
+573.877551020,p+s
+579.134693877,a
+590.854965986,a
+613.270068027,2.2
+631.432653061,p
+641.534693877,New Point
+648.556553287,a
+664.578321995,p
+671.033469387,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/4yaoqi.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,40 @@
+0.000000000,p
+11.085714285,New Point
+22.481632653,New Point
+27.444149659,1.2
+36.873287981,New Point
+44.048979591,New Point
+49.073287981,1.1
+53.502040816,New Point
+58.816145124,a
+67.183673469,New Point
+73.467936507,New Point
+78.024489795,New Point
+87.216326530,New Point
+93.861224489,New Point
+106.302040816,New Point
+115.024535147,1.4
+120.974013605,1.4
+128.556507936,a
+134.563265306,New Point
+142.391836734,p
+150.644897959,New Point
+158.708390022,s
+169.308299319,a
+181.510385487,a
+198.251972789,New Point
+208.865034013,p
+217.106575963,s
+227.694875283,a
+240.721269841,New Point
+255.554761904,2.1
+261.382222222,2.2
+263.564829931,4.2
+277.640997732,a
+286.594467120,2.3
+292.457142857,New Point
+296.820680272,New Point
+306.957233560,4.3
+314.444625850,p
+318.775147392,New Point
+318.937687074,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/5suolinnang.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,54 @@
+0.000000000,p
+4.969070294,s
+10.402539682,New Point
+30.696780045,a
+41.925736961,1.1
+54.218594104,New Point
+70.495782312,New Point
+83.986575963,New Point
+99.965804988,2.1
+113.028571428,a
+120.929523809,New Point
+125.897845804,2.2
+129.799546485,New Point
+140.024489795,2.3
+150.206507936,2.4
+160.189501133,1.3
+171.049818594,1.4
+174.629342403,3.4
+180.788344671,2.1
+189.355102040,a
+201.189138321,4.1
+208.765555555,4.2
+219.567891156,New Point
+234.951111111,New Point
+245.620680272,New Point
+256.487619047,New Point
+262.971428571,New Point
+270.883990929,New Point
+279.254784580,a
+294.905034013,New Point
+307.176780045,New Point
+320.351020408,New Point
+330.628571428,New Point
+338.351020408,New Point
+342.897959183,New Point
+347.045442176,New Point
+350.629795918,2.2
+359.119818594,New Point
+372.378412698,a
+387.715192743,New Point
+399.118367346,New Point
+406.790385487,New Point
+422.677551020,a
+434.800952380,5.2
+459.469523809,5.3
+463.851700680,5.4
+470.367346938,a 
+476.288752834,6.4
+481.956961451,7.2
+489.839750566,8.2
+494.468934240,New Point
+499.438004535,New Point
+504.825034013,New Point
+525.072834467,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/6liuyuexue.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,90 @@
+0.000000000,p
+9.636281179,New Point
+12.817414965,New Point
+20.271020408,New Point
+27.376326530,a
+38.707664399,New Point
+42.329977324,New Point
+53.220136054,New Point
+62.749319727,1.2
+68.162176870,New Point
+72.515918367,New Point
+80.132063492,New Point
+86.610430839,a
+96.177052154,New Point
+102.028480725,New Point
+109.249886621,New Point
+120.452471655,1.3
+125.155555555,New Point
+137.763990929,New Point
+153.135600907,New Point
+160.728526077,New Point
+167.276553287,a
+184.064580498,New Point
+201.084807256,a
+213.507482993,New Point
+233.469387755,New Point
+241.727959183,1.1
+250.008163265,New Point
+256.816326530,New Point
+263.128526077,a
+277.757097505,New Point
+296.391111111,s
+302.016326530,New Point
+313.155918367,New Point
+319.947755102,a
+330.938775510,New Point
+334.726530612,New Point
+338.563265306,New Point
+343.330612244,New Point
+356.960362811,New Point
+362.556371882,New Point
+370.404716553,New Point
+381.795918367,New Point
+390.024489795,New Point
+409.405646258,3.3
+420.982517006,4.1
+426.889795918,New Point
+428.907392290,New Point
+433.338775510,New Point
+440.189455782,5.2
+443.710113378,a
+458.824489795,New Point
+464.897959183,New Point
+473.567346938,New Point
+485.551020408,New Point
+494.057142857,New Point
+499.314285714,New Point
+507.959727891,New Point
+513.012244897,New Point
+520.034104308,New Point
+528.880907029,New Point
+534.302040816,New Point
+543.068299319,New Point
+551.203945578,1.2
+554.819138321,1.1
+563.461224489,New Point
+568.630839002,1.2
+577.420408163,New Point
+582.562857142,1.3
+589.647528344,New Point
+598.378231292,New Point
+612.495963718,New Point
+621.075056689,1.4
+624.570340136,New Point
+633.322970521,2.1
+638.318367346,New Point
+646.955102040,New Point
+655.595328798,6.2
+675.066167800,2.2
+686.801541950,2.4
+692.927142857,1.3
+702.001723356,3.3
+709.210521541,4.2
+715.406802721,a
+731.567891156,New Point
+743.926462585,4.3
+754.764625850,New Point
+769.625396825,p
+776.032653061,New Point
+777.287981859,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/6zhuofangcao_erhuangmanbanyuanban.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,77 @@
+0.000000000,p
+2.963265306,s
+10.541859410,New Point
+13.904240362,1.3
+22.562222222,2.1
+28.702040816,a
+36.808072562,3.3
+47.967346938,s
+58.235646258,a
+64.891882086,3.1
+71.408594104,3.2
+84.195555555,s
+94.354807256,4.2
+99.140068027,4.3
+106.434625850,5.1
+109.014603174,a
+117.847732426,5.2
+126.688072562,New Point
+139.176689342,s
+143.192063492,5.4
+148.236190476,New Point
+154.942857142,6.2
+161.802448979,New Point
+166.194557823,7.1
+170.550566893,New Point
+179.884988662,New Point
+189.999455782,7.2
+195.559183673,New Point
+205.896394557,7.3
+211.440907029,New Point
+221.795578231,7.4
+227.114376417,New Point
+231.006145124,8.1
+237.699501133,8.2
+243.066485260,New Point
+250.990657596,8.3
+258.577414965,New Point
+273.531065759,New Point
+285.582222222,New Point
+295.269523809,9.3
+300.768072562,New Point
+311.297959183,New Point
+322.597687074,9.4
+333.893877551,New Point
+341.126530612,New Point
+346.774852607,10.1
+349.583673469,New Point
+361.893877551,a
+373.012244897,New Point
+376.628934240,10.3
+387.076643990,New Point
+397.339863945,New Point
+406.171428571,New Point
+417.859115646,11.1
+424.356281179,New Point
+430.902426303,11.2
+442.130612244,a
+451.526530612,New Point
+459.871201814,New Point
+464.886712018,New Point
+468.679365079,1.2
+475.350000000,1.3
+485.355102040,a
+490.108956916,11.3
+500.390022675,New Point
+508.517006802,New Point
+514.577573696,2.2
+519.732244897,New Point
+530.227437641,12.1
+547.944489795,p
+553.261859410,New Point
+562.433741496,a
+576.647414965,12.2
+589.322448979,p
+594.106122448,New Point
+594.384399092,end
+18815.944852607,New Point
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/6zhuofangcao_xipimanban.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,37 @@
+0.000000000,p
+3.118367346,New Point
+5.893877551,New Point
+10.497959183,s
+14.013628117,1.4
+21.722675736,2.3
+30.098866213,a
+39.493877551,New Point
+44.907346938,3.1
+53.868798185,1.2
+61.453061224,New Point
+69.257142857,a
+77.469387755,New Point
+86.036802721,4.2
+90.840816326,New Point
+97.321337868,4.3
+100.995918367,a
+109.273469387,New Point
+118.251405895,1.3
+126.285714285,New Point
+133.820408163,a
+142.334693877,New Point
+148.261224489,New Point
+163.265306122,New Point
+167.166462585,4.4
+181.280090702,2.1
+187.814489795,5.2
+194.857142857,a
+202.579591836,New Point
+207.836734693,New Point
+218.771383219,2.3
+230.242494331,5.4
+240.445941043,6.1
+246.995918367,a
+252.619977324,3.2
+263.640816326,New Point
+263.871564625,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/7jinyunu01.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,21 @@
+0.000000000,p
+2.623854875,s
+7.909818594,1.2
+18.436643990,a
+29.861224489,New Point
+44.617029478,1.4
+49.272562358,2.1
+56.540408163,2.2
+61.983673469,New Point
+67.465464852,2.3
+72.121179138,a
+84.646643990,2.4
+93.412063492,3.1
+99.461224489,New Point
+113.800997732,a
+124.693877551,New Point
+132.493061224,New Point
+140.455011337,3.2
+153.763265306,New Point
+156.897233560,New Point
+157.175873015,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/7jinyunu04.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,42 @@
+0.000000000,p
+5.410249433,s
+13.653333333,a
+27.260226757,New Point
+39.681587301,1.1
+45.209251700,New Point
+51.153560090,New Point
+60.882721088,New Point
+64.412154195,New Point
+69.438866213,1.2
+72.724897959,New Point
+75.743492063,a 
+87.098004535,2.1
+94.764829931,1.3
+99.195646258,New Point
+112.338095238,2.3
+118.866870748,2.4
+125.399365079,New Point
+128.325079365,New Point
+134.373877551,a
+144.869297052,New Point
+151.069024943,New Point
+159.183673469,New Point
+164.977777777,New Point
+170.306757369,a
+187.752403628,2.4
+197.787573696,a
+207.355714285,4.1
+211.336417233,New Point
+217.094965986,New Point
+227.543945578,New Point
+235.450340136,New Point
+243.101065759,3.2
+251.980997732,5.2
+254.815782312,New Point
+260.643990929,a
+271.313560090,New Point
+275.945941043,New Point
+280.507823129,3.3
+290.267142857,1.1
+297.168979591,6.4
+297.192199546,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/7jinyunu06.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,27 @@
+0.032653061,p
+9.208163265,s
+13.560430839,1.4
+18.979591836,2.1
+27.297959183,a
+38.416326530,New Point
+46.702040816,New Point
+50.677551020,New Point
+59.110204081,New Point
+71.039569160,2.3
+75.929251700,New Point
+83.638276643,New Point
+88.293877551,a
+98.986666666,New Point
+104.768435374,New Point
+118.723628117,New Point
+130.372539682,3.1
+140.009523809,3.3
+153.855419501,p
+156.978503401,New Point
+170.271927437,New Point
+174.532789115,New Point
+185.504217687,New Point
+191.761995464,New Point
+205.686326530,4.1
+212.218775510,New Point
+216.456417233,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/7longfengchengxiang.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,59 @@
+0.000000000,p
+2.809614512,New Point
+6.826666666,New Point
+11.052698412,New Point
+14.976870748,New Point
+26.356190476,s
+36.251814058,2.1
+43.316757369,1.1
+51.489546485,1.2
+57.492607709,New Point
+68.410204081,a
+79.644444444,New Point
+94.365895691,New Point
+105.616326530,a
+117.098231292,New Point
+128.269523809,1.4
+139.452857142,3.1
+149.126530612,New Point
+152.741564625,2.1
+158.396371882,2.2
+165.197505668,2.3
+175.851451247,2.4
+184.881632653,New Point
+190.426848072,New Point
+200.950453514,3.2
+211.046167800,New Point
+223.329523809,New Point
+239.068843537,3.3
+245.600000000,s
+256.069659863,New Point
+259.065034013,New Point
+267.477551020,s
+280.264852607,New Point
+287.657142857,a
+297.586938775,New Point
+310.497233560,a
+320.760453514,New Point
+327.804512471,3.3
+342.693492063,3.4
+352.641451247,New Point
+366.759183673,New Point
+387.330612244,a
+396.921904761,New Point
+411.062857142,New Point
+426.047551020,4.2
+443.127006802,4.3
+451.117278911,New Point
+457.630544217,4.4
+470.505941043,New Point
+482.971428571,a
+502.101859410,1.1
+509.770884353,New Point
+526.460362811,5.2
+537.263310657,a
+546.411972789,New Point
+563.362539682,New Point
+576.208321995,5.4
+583.902040816,New Point
+585.991836734,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/7sangyuanjizi.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,44 @@
+0.000000000,1.1
+7.247006802,1.2
+21.548117913,p+sp
+27.353106575,New Point
+34.906122448,s
+56.998548752,1.2
+63.738775510,New Point
+83.963356009,New Point
+104.079977324,1.3
+118.723628117,a
+133.979138321,New Point
+154.021723356,1.4
+162.609342403,a
+176.277551020,New Point
+184.714739229,a
+193.942857142,New Point
+214.527188208,1.1
+225.129841269,p
+233.028571428,New Point
+245.061224489,New Point
+251.564988662,s
+265.914920634,a
+275.069387755,New Point
+307.827936507,2.2
+313.371428571,New Point
+322.316190476,p
+328.146938775,New Point
+342.958730158,a
+353.665306122,New Point
+359.793197278,p
+362.971428571,s
+374.421768707,a
+387.412244897,New Point
+397.420408163,New Point
+410.877097505,a
+423.363265306,New Point
+429.824580498,a
+445.485714285,New Point
+448.586303854,s
+453.973333333,a
+462.512494331,1.3
+470.575600907,p
+477.814217687,1.4
+480.049342403,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/8zuozhaidaoma01.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,44 @@
+0.000000000,p
+8.637823129,s
+25.425850340,a
+36.826848072,New Point
+49.977482993,2.3
+62.438458049,New Point
+70.240362811,s
+81.037641723,a
+87.239931972,3.4
+93.355623582,1.2
+101.865941043,a
+111.699591836,s
+122.183401360,a
+131.993832199,New Point
+135.441995464,New Point
+140.991564625,New Point
+150.611383219,1.2
+160.728526077,a
+166.011065759,New Point
+173.665306122,New Point
+180.529342403,a
+187.624489795,New Point
+192.043786848,4.2
+200.544943310,a
+205.879727891,New Point
+210.622403628,s
+219.492426303,a
+230.144580498,New Point
+243.043265306,a+p
+246.027029478,New Point
+258.081768707,4.3
+270.971904761,1.3
+278.453696145,New Point
+289.146485260,s
+298.152925170,a
+313.399727891,New Point
+320.934603174,New Point
+326.351020408,p
+335.644444444,New Point
+343.436734693,a
+352.163265306,New Point
+362.062335600,1.4
+368.593560090,New Point
+368.914285714,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/8zuozhaidaoma02.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,74 @@
+0.023219954,p
+2.716734693,New Point
+13.305850340,1.1
+28.398004535,a
+34.736553287,1.2
+47.310657596,New Point
+53.034376417,New Point
+60.127188208,1.3
+68.208616780,New Point
+72.190839002,a
+84.381315192,p
+93.133832199,2.2
+106.579591836,New Point
+119.464852607,2.3
+123.460498866,New Point
+129.836530612,2.1
+139.654308390,2.4
+148.702040816,a
+155.805895691,New Point
+164.186394557,2.2
+169.029659863,New Point
+174.381859410,p
+179.503809523,3.2
+195.670544217,4.2
+200.296825396,4.4
+207.632063492,2.3
+213.263673469,New Point
+216.618956916,New Point
+226.503560090,5.1
+229.807891156,New Point
+239.444172335,New Point
+245.038911564,3.1
+255.254399092,3.3
+261.528480725,5.3
+267.215238095,New Point
+275.608934240,3.4
+281.767641723,5.4
+290.620952380,New Point
+296.565260770,New Point
+302.846258503,New Point
+311.182222222,p
+318.386326530,4.2
+327.227210884,New Point
+333.220453514,6.2
+339.214943310,4.3
+350.546099773,5.1
+357.341156462,6.4
+363.113650793,New Point
+368.193015873,p
+375.543809523,5.3
+383.156009070,5.4
+387.967346938,New Point
+394.795918367,p
+399.801179138,s
+408.636371882,New Point
+416.635646258,New Point
+426.019931972,8.1
+433.184036281,8.2
+442.949659863,New Point
+447.575510204,New Point
+452.889795918,New Point
+458.171428571,New Point
+464.865306122,p
+469.559183673,New Point
+477.564489795,1.1
+485.873492063,8.3
+489.073469387,New Point
+497.355102040,p
+502.228571428,New Point
+516.228571428,New Point
+519.743854875,New Point
+525.560453514,New Point
+533.246258503,New Point
+533.501678004,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/9shangtiantai_erhaungkuaisanyan.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,20 @@
+0.000000000,p
+2.809614512,s
+8.782834467,1.3
+17.803582766,2.1
+21.989297052,a
+27.109297052,New Point
+35.777052154,2.2
+43.281995464,a
+50.802721088,2.4
+63.573968253,3.1
+70.304875283,2.1
+75.174603174,New Point
+85.124353741,a
+92.310204081,New Point
+103.869387755,New Point
+116.667664399,1.1
+124.188594104,3.2
+131.624489795,New Point
+135.929614512,2.3
+135.936326530,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/9shangtiantai_erhuangsanyan.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,43 @@
+0.000000000,1.1
+8.228571428,s
+13.962086167,1.3
+25.936689342,New Point
+30.305578231,1.4
+38.863242630,2.1
+46.901519274,2.2
+51.014240362,a
+58.560725623,New Point
+69.974126984,2.3
+79.992743764,a
+92.625850340,3.1
+99.683242630,3.3
+106.039977324,3.4
+111.467437641,4.1
+117.243650793,4.2
+124.279591836,1.1
+131.776757369,1.3
+139.110748299,New Point
+144.702653061,4.4
+151.052335600,5.1
+160.030612244,a
+166.255419501,2.2
+172.512244897,s
+177.945986394,5.3
+182.160544217,a
+191.216326530,New Point
+200.945487528,New Point
+206.634376417,New Point
+217.158480725,6.1
+231.084988662,New Point
+236.460408163,New Point
+242.253786848,New Point
+244.796371882,New Point
+248.488344671,New Point
+250.984489795,New Point
+254.069387755,a
+261.100317460,6.4
+268.120816326,New Point
+272.834467120,New Point
+286.262789115,7.1
+288.452312925,7.2
+294.011065759,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/9shangtiantai_erhuangyuanban.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,39 @@
+0.000000000,s
+5.503129251,a
+22.244716553,New Point
+28.980136054,1.2
+36.000000000,a
+44.440816326,New Point
+59.216326530,New Point
+68.476643990,2.1
+73.910204081,New Point
+83.627505668,2.2
+89.624489795,New Point
+99.702721088,2.3
+104.906122448,New Point
+110.688594104,3.1
+116.191723356,3.2
+122.236734693,New Point
+136.408163265,New Point
+145.731269841,3.3
+152.353287981,1.1
+166.693877551,New Point
+171.322448979,New Point
+175.444897959,New Point
+179.542857142,New Point
+183.273469387,New Point
+190.538775510,New Point
+198.762811791,New Point
+207.363265306,New Point
+216.816326530,New Point
+226.086893424,New Point
+234.857142857,New Point
+244.244897959,New Point
+249.861224489,New Point
+261.850929705,3.4
+269.730612244,New Point
+288.925895691,New Point
+301.516213151,4.2
+313.213968253,p
+318.775147392,New Point
+322.375510204,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/9tiannusanhua01.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,43 @@
+0.000000000,1.1
+10.634739229,s
+15.336780045,New Point
+23.296780045,1.2
+36.114285714,a
+50.653061224,New Point
+62.693877551,s
+67.941587301,a
+75.789931972,New Point
+89.350385487,New Point
+104.698775510,New Point
+112.288231292,1.3
+125.377913832,1.4
+135.836734693,s
+146.697845804,2.2
+157.221632653,2.3
+165.372517006,a
+176.471655328,New Point
+187.461587301,2.4
+211.412244897,New Point
+221.518367346,a
+231.688707482,New Point
+242.288616780,New Point
+261.168412698,3.4
+269.854580498,4.1
+279.394149659,4.2
+296.230589569,4.4
+312.767346938,New Point
+322.803809523,New Point
+335.804081632,a
+346.255963718,New Point
+360.555102040,s
+370.662018140,5.2
+384.774852607,5.3
+390.361972789,5.4
+398.919047619,6.1
+409.779591836,a
+419.445260770,New Point
+435.493877551,a
+445.691995464,6.2
+455.428571428,New Point
+463.005895691,New Point
+469.861224489,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_3/9tiannusanhua02.csv	Fri Aug 21 10:15:29 2015 +0100
@@ -0,0 +1,29 @@
+0.000000000,1.1
+4.527891156,New Point
+18.323832199,1.2
+25.567346938,s
+29.907301587,New Point
+35.131791383,a
+41.886213151,1.4
+47.977369614,2.1
+53.843718820,2.3
+60.100385487,2.4
+65.844920634,3.1
+71.853061224,New Point
+77.767346938,s+p
+82.012879818,a
+93.112018140,New Point
+99.583015873,3.2
+118.987755102,New Point
+133.156870748,4.1
+138.670045351,4.4
+145.108934240,s
+154.737777777,a
+168.066031746,a
+183.934693877,a
+195.314285714,New Point
+211.638253968,5.3
+228.494013605,1.2
+233.205600907,5.4
+241.240816326,New Point
+248.293877551,end
--- a/cnmf.py	Wed Jun 17 18:02:33 2015 +0100
+++ b/cnmf.py	Fri Aug 21 10:15:29 2015 +0100
@@ -19,139 +19,139 @@
 from utils import SegUtil
 
 # Algorithm params
-h = 8               # Size of median filter for features in C-NMF
-R = 15              # Size of the median filter for the activation matrix C-NMF
-rank = 4            # Rank of decomposition for the boundaries
-rank_labels = 6     # Rank of decomposition for the labels
-R_labels = 6        # Size of the median filter for the labels
+h = 8				# Size of median filter for features in C-NMF
+R = 15				# Size of the median filter for the activation matrix C-NMF
+rank = 4			# Rank of decomposition for the boundaries
+rank_labels = 6		# Rank of decomposition for the labels
+R_labels = 6		# Size of the median filter for the labels
 
 def cnmf(S, rank, niter=500):
-    """(Convex) Non-Negative Matrix Factorization.
+	"""(Convex) Non-Negative Matrix Factorization.
 
-    Parameters
-    ----------
-    S: np.array(p, N)
-        Features matrix. p row features and N column observations.
-    rank: int
-        Rank of decomposition
-    niter: int
-        Number of iterations to be used
+	Parameters
+	----------
+	S: np.array(p, N)
+		Features matrix. p row features and N column observations.
+	rank: int
+		Rank of decomposition
+	niter: int
+		Number of iterations to be used
 
-    Returns
-    -------
-    F: np.array
-        Cluster matrix (decomposed matrix)
-    G: np.array
-        Activation matrix (decomposed matrix)
-        (s.t. S ~= F * G)
-    """
-    nmf_mdl = pymf.CNMF(S, num_bases=rank)
-    nmf_mdl.factorize(niter=niter)
-    F = np.asarray(nmf_mdl.W)
-    G = np.asarray(nmf_mdl.H)
-    return F, G
+	Returns
+	-------
+	F: np.array
+		Cluster matrix (decomposed matrix)
+	G: np.array
+		Activation matrix (decomposed matrix)
+		(s.t. S ~= F * G)
+	"""
+	nmf_mdl = pymf.CNMF(S, num_bases=rank)
+	nmf_mdl.factorize(niter=niter)
+	F = np.asarray(nmf_mdl.W)
+	G = np.asarray(nmf_mdl.H)
+	return F, G
 
 def nmf(S, rank, nither=500):
 	nmf_mdl = pymf.NMF(S, num_bases=rank, niter=nither)
 	nmf_mdl.factorize()
-    F = np.asarray(nmf_mdl.W)
-    G = np.asarray(nmf_mdl.H)
-    return F, G
+	F = np.asarray(nmf_mdl.W)
+	G = np.asarray(nmf_mdl.H)
+	return F, G
 	
 	
 def most_frequent(x):
-    """Returns the most frequent value in x."""
-    return np.argmax(np.bincount(x))
+	"""Returns the most frequent value in x."""
+	return np.argmax(np.bincount(x))
 
 
 def compute_labels(X, rank, R, bound_idxs, niter=300):
-    """Computes the labels using the bounds."""
+	"""Computes the labels using the bounds."""
 
-    X = X.T
-    try:
-        F, G = cnmf(X, rank, niter=niter)
-    except:
-        return [1]
+	X = X.T
+	try:
+		F, G = cnmf(X, rank, niter=niter)
+	except:
+		return [1]
 
-    label_frames = filter_activation_matrix(G.T, R)
-    label_frames = np.asarray(label_frames, dtype=int)
+	label_frames = filter_activation_matrix(G.T, R)
+	label_frames = np.asarray(label_frames, dtype=int)
 
-    # Get labels from the label frames
-    labels = []
-    bound_inters = zip(bound_idxs[:-1], bound_idxs[1:])
-    for bound_inter in bound_inters:
-        if bound_inter[1] - bound_inter[0] <= 0:
-            labels.append(np.max(label_frames) + 1)
-        else:
-            labels.append(most_frequent(
-                label_frames[bound_inter[0]:bound_inter[1]]))
+	# Get labels from the label frames
+	labels = []
+	bound_inters = zip(bound_idxs[:-1], bound_idxs[1:])
+	for bound_inter in bound_inters:
+		if bound_inter[1] - bound_inter[0] <= 0:
+			labels.append(np.max(label_frames) + 1)
+		else:
+			labels.append(most_frequent(
+				label_frames[bound_inter[0]:bound_inter[1]]))
 
-    return labels
+	return labels
 
 
 def filter_activation_matrix(G, R):
-    """Filters the activation matrix G, and returns a flattened copy."""
-    idx = np.argmax(G, axis=1)
-    max_idx = np.arange(G.shape[0])
-    max_idx = (max_idx, idx.flatten())
-    G[:, :] = 0
-    G[max_idx] = idx + 1
-    G = np.sum(G, axis=1)
-    G = SegUtil.median_filter(G[:, np.newaxis], R)
-    return G.flatten()
+	"""Filters the activation matrix G, and returns a flattened copy."""
+	idx = np.argmax(G, axis=1)
+	max_idx = np.arange(G.shape[0])
+	max_idx = (max_idx, idx.flatten())
+	G[:, :] = 0
+	G[max_idx] = idx + 1
+	G = np.sum(G, axis=1)
+	G = SegUtil.median_filter(G[:, np.newaxis], R)
+	return G.flatten()
 
 
 def segmentation(X, rank=4, R=15, h=8, niter=300, CNMF=True):
-    """
-    Gets the segmentation (boundaries and labels) from the factorization
-    matrices.
+	"""
+	Gets the segmentation (boundaries and labels) from the factorization
+	matrices.
 
-    Parameters
-    ----------
-    X: np.array()
-        Features matrix (e.g. chromagram)
-    rank: int
-        Rank of decomposition
-    R: int
-        Size of the median filter for activation matrix
-    niter: int
-        Number of iterations for k-means
-    bound_idxs : list
-        Use previously found boundaries (None to detect them)
+	Parameters
+	----------
+	X: np.array()
+		Features matrix (e.g. chromagram)
+	rank: int
+		Rank of decomposition
+	R: int
+		Size of the median filter for activation matrix
+	niter: int
+		Number of iterations for k-means
+	bound_idxs : list
+		Use previously found boundaries (None to detect them)
 	CNMF : bool
 		If True, use CNMF; otherwise use NMF
 		
-    Returns
-    -------
-    bounds_idx: np.array
-        Bound indeces found
-    labels: np.array
-        Indeces of the labels representing the similarity between segments.
-    """
+	Returns
+	-------
+	bounds_idx: np.array
+		Bound indeces found
+	labels: np.array
+		Indeces of the labels representing the similarity between segments.
+	"""
 
-    # Filter
-    X = SegUtil.median_filter(X, M=h)
-    X = X.T
+	# Filter
+	X = SegUtil.median_filter(X, M=h)
+	X = X.T
 
-    # Find non filtered boundaries
-    bound_idxs = None
-    while True:
-        if bound_idxs is None:
-            try:
-                if CNMF: F, G = cnmf(X, rank, niter=niter)
+	# Find non filtered boundaries
+	bound_idxs = None
+	while True:
+		if bound_idxs is None:
+			try:
+				if CNMF: F, G = cnmf(X, rank, niter=niter)
 				else: F, G = nmf(X, rank, niter=niter)
-            except:
-                return np.empty(0), [1]
+			except:
+				return np.empty(0), [1]
 
-            # Filter G
-            G = filter_activation_matrix(G.T, R)
-            if bound_idxs is None:
-                bound_idxs = np.where(np.diff(G) != 0)[0] + 1
+			# Filter G
+			G = filter_activation_matrix(G.T, R)
+			if bound_idxs is None:
+				bound_idxs = np.where(np.diff(G) != 0)[0] + 1
 
-        if len(np.unique(bound_idxs)) <= 2:
-            rank += 1
-            bound_idxs = None
-        else:
-            break
+		if len(np.unique(bound_idxs)) <= 2:
+			rank += 1
+			bound_idxs = None
+		else:
+			break
 
-    return G, bound_idxs
+	return G, bound_idxs
--- a/novelty.py	Wed Jun 17 18:02:33 2015 +0100
+++ b/novelty.py	Fri Aug 21 10:15:29 2015 +0100
@@ -88,7 +88,7 @@
 				
 	return kernel	
 	
-def segmentation(ssm, peak_picker=peak_picker, kernel_size=48, normalise=False, plot=False):
+def process(ssm, peak_picker=peak_picker, kernel_size=48, normalise=False, plot=False):
 	'''Detect segment boundaries in the ssm.'''
 	# peak_picker for the 1st round boudary detection
 
@@ -101,4 +101,4 @@
 	return novelty, smoothed_novelty, novelty_peaks
 	
 def plot_detection(smoothed_novelty, novelty_peaks):
-	pass
\ No newline at end of file
+	pass
--- a/utils/SegUtil.py	Wed Jun 17 18:02:33 2015 +0100
+++ b/utils/SegUtil.py	Fri Aug 21 10:15:29 2015 +0100
@@ -20,12 +20,13 @@
 from scipy.ndimage import filters, zoom
 from scipy import signal
 from scipy.signal import correlate2d, convolve2d, filtfilt, resample, butter
-import pylab as plt
+# import pylab as plt
 from scipy.spatial.distance import squareform, pdist
 from scipy.ndimage.filters import maximum_filter, minimum_filter, percentile_filter, uniform_filter
-from scipy.ndimage.filters import median_filter as med_filter
+from scipy.ndimage.filters import median_filter as med_filter # median_filter is a user defined function in this script
 from sklearn.metrics.pairwise import pairwise_distances
 
+from GmmMetrics import GmmDistance
 
 def lognormalize_chroma(C):
 	"""Log-normalizes chroma such that each vector is between -80 to 0."""
@@ -47,6 +48,7 @@
 	if not os.path.exists(directory):
 		os.makedirs(directory)
 
+
 def median_filter(X, M=8):
 	"""Median filter along the first axis of the feature matrix X."""
 	for i in xrange(X.shape[1]):
@@ -279,22 +281,6 @@
 
 	return rec
 
-def finiteMax(X):
-	'''Return the smallest finite value in the array'''
-	if not (np.isnan(X).any() or np.isposinf(X).any()):
-		return np.max(X)
-	data = np.sort(np.ndarray.flatten(X))
-	pos = np.where(data == np.inf)[0]
-	fMax = 0
-	return fMax
-
-def finiteMin(feature):
-	'''Return the smallest finite value in the array'''
-	if not (np.isnan(X).any() or np.isinf(X).any()):
-		return np.min(X)
-	fMin = 0
-	return fMin
-
 def lp(signal, fc=0.34, axis=-1):
 	'''Low pass filter function
 	signal: Raw signal to be smoothed.
@@ -304,6 +290,7 @@
 	lp_smoothed_signal = filtfilt(bCoeffs, aCoeffs, signal, axis)
 	return lp_smoothed_signal
 
+
 def hp(signal, fc=0.34, axis=-1):
 	'''Low pass filter function
 	signal: Raw signal to be smoothed.
@@ -312,7 +299,8 @@
 	bCoeffs, aCoeffs = butter(2, fc, 'highpass')
 	hp_smoothed_signal = filtfilt(bCoeffs, aCoeffs, signal, axis)
 	return hp_smoothed_signal
-	
+
+
 def getMean(feature, winlen, stepsize):
 	means = []
 	steps = int((feature.shape[0] - winlen + stepsize) / stepsize)
@@ -343,17 +331,18 @@
 	if norm == 'simple':
 		ssm = 1 - (dm - np.min(dm)) / (np.max(dm) - np.min(dm))
 	if norm == 'exp': # Use with cosine metric only
-		ssm = np.exp(dm - 1)
+		ssm = 1 - np.exp(dm - 1)
 	if reduce:
 		ssm = reduceSSM(ssm)
 	return ssm
 
+
 def enhanceSSM(ssm, fc=0.34, med_size=(5,5), max_size=(5,5), min_size=(5,5), filter_type='min', axis=-1):
 	'''A series of filtering for SSM enhancement
 	fc: cutoff frequency for LP filtering.
 	med_size: Median filter window size.
 			  int or tuple. If using an integer for a 2d input, axis must be specified.
-	filter_type: Select either to use maximum filter or minimum filter.
+	filter_type: Select either to use maximum filter or minimum filter according to the distance metric with which the SSM was computed.
 			float ['min', 'max', None]
 	max_size: Maximum filter window size.
 			  int or tuple. If using an integer for a 2d input, axis must be specified.
@@ -375,16 +364,17 @@
 	else:
 		enhanced_ssm = ssm_med
 	return enhanced_ssm
-	
+
+
 def reduceSSM(ssm, maxfilter_size = 2, remove_size=50):
 	'''Adaptive thresholding using OTSU method
-	Required package: skimage (0.10+)'''
+	Required package: skimage (0.10+) -- NOT installed on ignis, do NOT call this function!'''
 	
 	from skimage.morphology import disk
 	# from skimage.filters import threshold_otsu, rank #skimage 0.12
 	from skimage.filter.rank import otsu #skimage 0.10
 	from skimage.filter import threshold_otsu
-	
+
 	reduced_ssm = copy(ssm)
 	reduced_ssm[reduced_ssm<0.75] = 0
 	# # reduced_ssm = maximum_filter(reduced_ssm,size=maxfilter_size)
@@ -416,6 +406,25 @@
 
 	return feature_array		
 
+def normaliseArray(X):
+	'''Normalise 1d array.'''
+	if np.max(X) == np.min(X):
+		return None
+	return (X - np.min(X)) / (np.max(X) - np.min(X))
+	
+def pairwiseSKL(self, gmm_list):
+	'''Compute pairwise symmetrised KL divergence of a list of GMMs.'''
+	n_GMMs = len(gmm_list)
+	distance_matrix = np.zeros((n_GMMs, n_GMMs))
+	for i in xrange(n_GMMs):
+		for j in xrange(i, n_GMMs):
+			distance_matrix[i][j] = gmm_list[i].skl_distance_full(gmm_list[j])
+			distance_matrix[j][i] = distance_matrix[i][j]
+
+	np.fill_diagonal(distance_matrix, 0.0)
+	distance_matrix[np.isinf(distance_matrix)] = np.finfo(np.float64).max
+	
+	return distance_matrix
 
 def getRolloff(data, tpower, filterbank, thresh=0.9):
 	nFrames = data.shape[0]