changeset 18:b4bf37f94e92

prepared to add another annotation
author mitian
date Wed, 09 Dec 2015 16:27:10 +0000
parents c01fcb752221
children 890cfe424f4a
files HSeg.py SegEval.py annotation/qupujicheng_annotation_30_3/10hongniang02.csv annotation/qupujicheng_annotation_30_3/1bawangbieji02.csv annotation/qupujicheng_annotation_30_4/10hongniang01.csv annotation/qupujicheng_annotation_30_4/10hongniang02.csv annotation/qupujicheng_annotation_30_4/10hongniang04.csv annotation/qupujicheng_annotation_30_4/1bawangbieji02.csv annotation/qupujicheng_annotation_30_4/1yuzhoufeng01.csv annotation/qupujicheng_annotation_30_4/1yuzhoufeng02.csv annotation/qupujicheng_annotation_30_4/2kongchengji_xipimanban.csv annotation/qupujicheng_annotation_30_4/2lilingbei.csv annotation/qupujicheng_annotation_30_4/2wenzhaoguan.csv annotation/qupujicheng_annotation_30_4/2xucepaocheng.csv annotation/qupujicheng_annotation_30_4/3dayushajia_xipikuaisanyan.csv annotation/qupujicheng_annotation_30_4/3nuqijie0215-0517.csv annotation/qupujicheng_annotation_30_4/4qingguance.csv annotation/qupujicheng_annotation_30_4/4yaoqi.csv annotation/qupujicheng_annotation_30_4/5suolinnang.csv annotation/qupujicheng_annotation_30_4/6liuyuexue.csv annotation/qupujicheng_annotation_30_4/6zhuofangcao_erhuangmanbanyuanban.csv annotation/qupujicheng_annotation_30_4/6zhuofangcao_xipimanban.csv annotation/qupujicheng_annotation_30_4/7jinyunu01.csv annotation/qupujicheng_annotation_30_4/7jinyunu04.csv annotation/qupujicheng_annotation_30_4/7jinyunu06.csv annotation/qupujicheng_annotation_30_4/7longfengchengxiang.csv annotation/qupujicheng_annotation_30_4/7sangyuanjizi.csv annotation/qupujicheng_annotation_30_4/8zuozhaidaoma01.csv annotation/qupujicheng_annotation_30_4/8zuozhaidaoma02.csv annotation/qupujicheng_annotation_30_4/9shangtiantai_erhaungkuaisanyan.csv annotation/qupujicheng_annotation_30_4/9shangtiantai_erhuangsanyan.csv annotation/qupujicheng_annotation_30_4/9shangtiantai_erhuangyuanban.csv annotation/qupujicheng_annotation_30_4/9tiannusanhua01.csv annotation/qupujicheng_annotation_30_4/9tiannusanhua02.csv cnmf.py novelty.py sf.py utils/OnsetPlotProc.py utils/PeakPickerUtil.py utils/RankClustering.py utils/xmeans.py
diffstat 41 files changed, 1994 insertions(+), 702 deletions(-) [+]
line wrap: on
line diff
--- a/HSeg.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/HSeg.py	Wed Dec 09 16:27:10 2015 +0000
@@ -134,16 +134,16 @@
 		
 		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 = 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 = []	
@@ -261,16 +261,22 @@
 		else:
 			return None
 			
-	def secondRoundDetection(self, peak_candidates, candidates_conf, feature, peak_verifier=None, tol=3, thresh=0.5):
+	def secondRoundDetection(self, peak_candidates, candidates_conf, feature, peak_verifier=None, tol=3, thresh1=0.4, thresh2=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
+			# Bypass peak candidates with low confidence
+			if candidates_conf[x] < thresh1: continue
 			
+			# If with high confidence, keep it straight
+			if candidates_conf[x] > 0.7:
+				peaks.append(x)
+				continue
+
+			# 2nd round detection for questionable peaks
 			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
@@ -278,17 +284,20 @@
 			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:]
+			local_conf, local_peaks = novelty_S.process(local_ssm,peak_verifier,100)[-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:
+			# if np.max(local_conf[local_peaks]) > thresh2:
+			if local_conf[tol_win] >= thresh2: #v2
 				local_bound = x - tol_win + np.argmax(local_conf)
 				peaks.append(np.rint(local_bound))
-				
+			
+			# remove very closely located peaks (duplicates from different rounds of detection)
+ 				
 			peaks.sort()
 		return peaks
 			
@@ -316,14 +325,14 @@
 		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_a = (100 - 20) / 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.QuadThresh_c = (100 - 20) / 1500.0
+		peak_verifier.params.rawSensitivity = 20
 		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.preWin = 20
+		peak_verifier.params.postWin = 20 + 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		
@@ -332,21 +341,24 @@
 		# Getting aggregated features.
 		featureRate = float(self.SampleRate) / self.stepSize
 		aggregation_window, aggregation_step = 20, 10
-		
+		tempo_step = 0.204995725 * featureRate
+
 		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_files = audio_files[:2]
 		audio_list = []
 		
 		# Use mfccs feature 1st round segmentation (coarse)
-		feature_list1 = ['mfcc_harmonic']
+		feature_list1 =['mfcc_harmonic']
+		# feature_list1 = ['ti_15_30_4_03_05', 'tir_15_30_4_03_05'] 
 		feature_list1 = [join(options.F1, f) for f in feature_list1]
-		feature_list2 = ['dct']
+		# feature_list2 = ['gt_stft_lpc']
+		feature_list2 = ['chromagram_harmonic']
 		feature_list2 = [join(options.F2, f) for f in feature_list2]
 
 		# Prepare output files.
-		outfile1 = join(options.OUTPUT, 'verified_novelty.csv')
+		outfile1 = join(options.OUTPUT, 'tbhm_verified_novelty_tol1th103th205_07_v2.csv')
 		self.writeVerifiedHeader(outfile1)
 		
 		# For each audio file, load specific features
@@ -374,7 +386,8 @@
 			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:])
+						ao.ssm_timestamps = np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[1:,0]
+						featureset1.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[1:,1:14])
 						break
 			if len(feature_list1) > 1:
 				n_frame = np.min([x.shape[0] for x in featureset1])
@@ -383,13 +396,13 @@
 			else:
 				ao.features1 = featureset1[0]
 
-			ao.ssm_timestamps = np.arange(0, ao.gt[-1], float(self.stepSize)/self.SampleRate)	
+			# 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:])
+						featureset2.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:14])
 						break
 			if len(feature_list2) > 1:
 				n_frame = np.min([x.shape[0] for x in featureset2])
@@ -406,12 +419,18 @@
 			step = ao.features1.shape[0] / aggregation_step
 			ao.features1 = resample(ao.features1, step)
 			ao.features1 = normaliseFeature(ao.features1)
+			ao.features2 = normaliseFeature(ao.features2)
 						
 			pca.fit(ao.features1)
 			ao.features1 = pca.transform(ao.features1)
+			pca.fit(ao.features2)
+			ao.features2 = pca.transform(ao.features2)
+
+
 			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)
 			
@@ -425,14 +444,16 @@
 			# 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_candidates = np.array(map(lambda x: int((np.rint(x*tempo_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_conf = zoom(peak_conf, tempo_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 = self.secondRoundDetection(peak_candidates, peak_conf, ao.features2, peak_verifier, tol=1, thresh1=0.3, thresh2=0.5)
 			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)
--- a/SegEval.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/SegEval.py	Wed Dec 09 16:27:10 2015 +0000
@@ -16,7 +16,7 @@
 from copy import copy
 
 import matplotlib
-# matplotlib.use('Agg')
+matplotlib.use('Agg')
 import matplotlib.pyplot as plt
 import matplotlib.gridspec as gridspec
 import numpy as np
@@ -29,13 +29,13 @@
 from sklearn.metrics.pairwise import pairwise_distances
 
 # Load dependencies
-from utils.SegUtil import getMean, getStd, getDelta, getSSM, reduceSSM, upSample, normaliseFeature
+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
-from utils.PathTracker import PathTracker
+# from utils.PathTracker import PathTracker
 from utils.OnsetPlotProc import onset_plot, plot_on
 
 # Load bourdary retrieval utilities
@@ -46,9 +46,10 @@
 import novelty as novelty_S
 
 # Algorithm params
+# cnmf
 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 = 3            # Rank of decomposition for the boundaries
+R = 12              # Size of the median filter for the activation matrix C-NMF
+rank = 4            # Rank of decomposition for the boundaries
 rank_labels = 16     # Rank of decomposition for the labels
 R_labels = 4        # Size of the median filter for the labels
 # Foote
@@ -66,19 +67,20 @@
 	op.add_option('-g', '--gammatonegram-features', action="store", dest="GF", default='/Volumes/c4dm-03/people/mit/features/gammatonegram/qupujicheng/2048', type="str", help="Loading gammatone features from.." )
 	op.add_option('-s', '--spectrogram-features', action="store", dest="SF", default='/Volumes/c4dm-03/people/mit/features/spectrogram/qupujicheng/2048', type="str", help="Loading spectral features from.." )
 	op.add_option('-t', '--tempogram-features', action="store", dest="TF", default='/Volumes/c4dm-03/people/mit/features/tempogram/qupujicheng/tempo_features_6s', type="str", help="Loading tempogram features from.." )
-	op.add_option('-f', '--featureset', action="store", dest="FEATURES", default='[0, 1, 2, 3]', type="str", help="Choose feature subsets (input a list of integers) used for segmentation -- gammtone, chroma, timbre, tempo -- 0, 1, 2, 3." )
 	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('-o', '--ouput', action="store", dest="OUTPUT", default='/Volumes/c4dm-03/people/mit/segmentation/gammatone/qupujicheng', type="str", help="Write segmentation results to ")
+	op.add_option('-d', '--dataset', action="store", dest="DATASET", default='qupujicheng', type="str", help="Specify datasets")
 
-	# boundary retrieval options
+	# parameterization options
 	op.add_option('-b', '--bounrary-method', action="store", dest="BOUNDARY", type='choice', choices=['novelty', 'cnmf', 'foote', 'sf'], default='novelty', help="Choose boundary retrieval algorithm ('novelty', 'cnmf', 'sf', 'fmc2d')." )
 	op.add_option('-l', '--labeling-method', action="store", dest="LABEL", type='choice', choices=['cnmf', 'fmc2d'], default='cnmf', help="Choose boundary labeling algorithm ('cnmf', 'fmc2d')." )
+	op.add_option('-x', '--experiment', action="store", dest="EXPERIMENT", type='choice', choices=['all',  'individual', 'fuse_feature', 'fuse_ssm', 'fuse_novelty', 'fuse_bounds'], default='all', help="Specify experiment to execute." )
 	
 	# Plot/print/mode options
 	op.add_option('-p', '--plot', action="store_true", dest="PLOT", default=False, help="Save plots")
 	op.add_option('-e', '--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()
 
@@ -87,24 +89,23 @@
 
 class AudioObj():
 	__slots__ = ['name', 'feature_list', 'gt', 'label', 'gammatone_features', 'tempo_features', 'timbre_features', 'harmonic_features', 'combined_features',\
-	'gammatone_ssm', 'tempo_ssm', 'timbre_ssm', 'harmonic_ssm', 'combined_ssm', 'ssm', 'ssm_timestamps', 'tempo_timestamps']
+	'gammatone_ssm', 'tempo_ssm', 'timbre_ssm', 'harmonic_ssm', 'combined_ssm', 'ssm', 'ssm_timestamps', 'timestamps']
 
 class EvalObj():
-	__slots__ = ['TP', 'FP', 'FN', 'P', 'R', 'F', 'AD', 'DA']
+	__slots__ = ['TP', 'FP', 'FN', 'P', 'R', 'F', 'AD', 'DA', 'detection']
 
 	
 class SSMseg(object):
 	'''The main segmentation object'''
 	def __init__(self):
-		self.SampleRate = 44100
+		self.SampleRate = 44100.0
 		self.NqHz = self.SampleRate/2
-		self.timestamp = []
 		self.previousSample = 0.0
 		self.featureWindow = 6.0
 		self.featureStep = 3.0
-		self.kernel_size = 64 # Adjust this param according to the feature resolution.pq
-		self.blockSize = 2048
-		self.stepSize = 1024
+		self.kernel_size = 100 # Adjust this param according to the feature resolution.pq
+		self.blockSize = 2048.0
+		self.stepSize = 1024.0
 
 		'''NOTE: Match the following params with those used for feature extraction!'''
 		
@@ -122,19 +123,19 @@
 		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.threshold = 10
+		self.confidence_threshold = 0.4
 		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.whitening_on = True
 		self.aCoeffs = [1.0000, -0.5949, 0.2348]
 		self.bCoeffs = [0.1600,	 0.3200, 0.1600]
 		self.cutoff = 0.34
-		self.medianWin = 7
-				
+		self.medianWin = 10
+		self.lin = 0.5		
 		if plot_on : onset_plot.reset()
 			
 	def pairwiseF(self, annotation, detection, tolerance=3.0, combine=1.0, idx2time=None):
@@ -148,40 +149,44 @@
 		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)
 		
-		if idx2time != None:
-			# Map detected idxs to real time
-			detection = [idx2time[int(np.rint(i))] for i in detection] + [annotation[-1]]
-		# print 'detection', detection
-		detection = np.append(detection, annotation[-1])
-		
 		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):
-					res.TP = res.TP + 1.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 = max(0, gt - res.TP)
+		res.FN = gt - res.TP
 
 		res.AD = np.mean(D_AD)		
-		res.DA = np.mean(D_DA)
-		
+		res.DA = np.mean(D_DA)	
 		
 		if res.TP == 0:
 			return res
 
-		res.P = res.TP / float(dt)
-		res.R = res.TP / float(gt)
+		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
 		
@@ -190,20 +195,18 @@
 		
 		with open(filename, 'a') as f:
 			csvwriter = csv.writer(f, delimiter=',')
-			csvwriter.writerow(['audio', 'gammatone_tp_05', 'gammatone_fp_05', 'gammatone_fn_05', 'gammatone_P_05', 'gammatone_R_05', 'gammatone_F_05', 'gammatone_AD_05', 'gammatone_DA_05', 'gammatone_tp_3', \
-			'gammatone_fp_3', 'gammatone_fn_3', 'gammatone_P_3', 'gammatone_R_3', 'gammatone_F_3', 'gammatone_AD_3', 'gammatone_DA_3', 'harmonic_tp_05', 'harmonic_fp_05', 'harmonic_fn_05', 'harmonic_P_05', \
+			csvwriter.writerow(['audio', 'harmonic_tp_05', 'harmonic_fp_05', 'harmonic_fn_05', 'harmonic_P_05', \
 			'harmonic_R_05', 'harmonic_F_05', 'harmonic_AD_05', 'harmonic_DA_05', 'harmonic_tp_3', 'harmonic_fp_3', 'harmonic_fn_3', 'harmonic_P_3', 'harmonic_R_3', 'harmonic_F_3', 'harmonic_AD_3', 'harmonic_DA_3', \
 			'timbre_tp_05', 'timbre_fp_05', 'timbre_fn_05', 'timbre_P_05', 'timbre_R_05', 'timbre_F_05', 'timbre_AD_05', 'timbre_DA_05', 'timbre_tp_3', 'timbre_fp_3', 'timbre_fn_3', 'timbre_P_3', 'timbre_R_3', \
 			'timbre_F_3', 'timbre_AD_3', 'timbre_DA_3',	 'tempo_tp_05', 'tempo_fp_05', 'tempo_fn_05', 'tempo_P_05', 'tempo_R_05', 'tempo_F_05', 'tempo_AD_05', 'tempo_DA_05', \
 			'tempo_tp_3', 'tempo_fp_3', 'tempo_fn_3', 'tempo_P_3', 'tempo_R_3', 'tempo_F_3', 'tempo_AD_3', 'tempo_DA_3'])
 	
-	def writeIndividualRes(self, filename, ao_name, gt_res_05, gt_res_3, harmonic_res_05, harmonic_res_3, timbre_res_05, timbre_res_3, tempo_res_05, tempo_res_3):
+	def writeIndividualRes(self, filename, ao_name, harmonic_res_05, harmonic_res_3, timbre_res_05, timbre_res_3, tempo_res_05, tempo_res_3):
 		'''Write result of single detection for individual features.'''
 		
 		with open(filename, 'a') as f:
 			csvwriter = csv.writer(f, delimiter=',')
-			csvwriter.writerow([ao_name, gt_res_05.TP, gt_res_05.FP, gt_res_05.FN, gt_res_05.P, gt_res_05.R, gt_res_05.F, gt_res_05.AD, gt_res_05.DA, gt_res_3.TP, gt_res_3.FP, gt_res_3.FN, gt_res_3.P, \
-			gt_res_3.R, gt_res_3.F, gt_res_3.AD, gt_res_3.DA, harmonic_res_05.TP, harmonic_res_05.FP, harmonic_res_05.FN, harmonic_res_05.P, harmonic_res_05.R, harmonic_res_05.F, harmonic_res_05.AD, harmonic_res_05.DA, \
+			csvwriter.writerow([ao_name, harmonic_res_05.TP, harmonic_res_05.FP, harmonic_res_05.FN, harmonic_res_05.P, harmonic_res_05.R, harmonic_res_05.F, harmonic_res_05.AD, harmonic_res_05.DA, \
 			harmonic_res_3.TP, harmonic_res_3.FP, harmonic_res_3.FN, harmonic_res_3.P, harmonic_res_3.R, harmonic_res_3.F, harmonic_res_3.AD, harmonic_res_3.DA, timbre_res_05.TP, timbre_res_05.FP, \
 			timbre_res_05.FN, timbre_res_05.P, timbre_res_05.R, timbre_res_05.F, timbre_res_05.AD, timbre_res_05.DA, timbre_res_3.TP, timbre_res_3.FP, timbre_res_3.FN, timbre_res_3.P, timbre_res_3.R, timbre_res_3.F, \
 			timbre_res_3.AD, timbre_res_3.DA, tempo_res_05.TP, tempo_res_05.FP, tempo_res_05.FN, tempo_res_05.P, tempo_res_05.R, tempo_res_05.F, tempo_res_05.AD, tempo_res_05.DA, tempo_res_3.TP, tempo_res_3.FP, \
@@ -214,39 +217,53 @@
 		
 		with open(filename, 'a') as f:
 			csvwriter = csv.writer(f, delimiter=',')
-			csvwriter.writerow(['audio', 'gt_tb_P_0.5', 'gt_tb_R_0.5', 'gt_tb_F_0.5', 'gt_tb_P_3', 'gt_tb_R_3', 'gt_tb_F_3', 'gt_tp_P_0.5', 'gt_tp_R_0.5', 'gt_tp_F_0.5', 'gt_tp_P_3', 'gt_tp_R_3', 'gt_tp_F_3',\
-			'gt_hm_P_0.5', 'gt_hm_R_0.5', 'gt_hm_F_0.5', 'gt_hm_P_3', 'gt_hm_R_3', 'gt_hm_F_3', 'tb_tp_P_0.5', 'tb_tp_R_0.5', 'tb_tp_F_0.5', 'tb_tp_P_3', 'tb_tp_R_3', 'tb_tp_F_3', 'hm_tb_P_0.5', 'hm_tb_R_0.5', 'hm_tb_F_0.5', \
-			'hm_tb_P_3', 'hm_tb_R_3', 'hm_tb_F_3', 'hm_tp_P_0.5', 'hm_tp_R_0.5', 'hm_tp_F_0.5', 'hm_tp_P_3', 'hm_tp_R_3', 'hm_tp_F_3', 'gt_tb_tp_P_0.5', 'gt_tb_tp_R_0.5', 'gt_tb_tp_F_0.5', 'gt_tb_tp_P_3', 'gt_tb_tp_R_3', \
-			'gt_tb_tp_F_3', 'gt_hm_tb_P_0.5', 'gt_hm_tb_R_0.5', 'gt_hm_tb_F_0.5', 'gt_hm_tb_P_3', 'gt_hm_tb_R_3', 'gt_hm_tb_F_3', 'gt_hm_tp_P_0.5', 'gt_hm_tp_R_0.5', 'gt_hm_tp_F_0.5', 'gt_hm_tp_P_3', 'gt_hm_tp_R_3', 'gt_hm_tp_F_3', \
-			'hm_tb_tp_P_0.5', 'hm_tb_tp_R_0.5', 'hm_tb_tp_F_0.5', 'hm_tb_tp_P_3', 'hm_tb_tp_R_3', 'hm_tb_tp_F_3', 'gt_hm_tb_tp_P_0.5', 'gt_hm_tb_tp_R_0.5', 'gt_hm_tb_tp_F_0.5', 'gt_hm_tb_tp_P_3', 'gt_hm_tb_tp_R_3', 'gt_hm_tb_tp_F_3'])
+			csvwriter.writerow(['audio', 'hm_tb_P_0.5', 'hm_tb_R_0.5', 'hm_tb_F_0.5', 'hm_tb_P_3', 'hm_tb_R_3', 'hm_tb_F_3', 'hm_tp_P_0.5', 'hm_tp_R_0.5',\
+			'hm_tp_F_0.5', 'hm_tp_P_3', 'hm_tp_R_3', 'hm_tp_F_3', 'tb_tp_P_0.5', 'tb_tp_R_0.5', 'tb_tp_F_0.5', 'tb_tp_P_3', 'tb_tp_R_3', 'tb_tp_F_3',\
+			'hm_tb_tp_P_0.5', 'hm_tb_tp_R_0.5', 'hm_tb_tp_F_0.5', 'hm_tb_tp_P_3', 'hm_tb_tp_R_3', 'hm_tb_tp_F_3'])
 		
-	def writeCombinedRes(self, filename, ao_name, gt_hm_res_05, gt_hm_res_3, gt_tb_res_05, gt_tb_res_3, gt_tp_res_05, gt_tp_res_3, hm_tb_res_05, hm_tb_res_3, hm_tp_res_05, hm_tp_res_3, \
-	tb_tp_res_05, tb_tp_res_3, gt_hm_tb_res_05, gt_hm_tb_res_3, gt_hm_tp_res_05, gt_hm_tp_res_3, gt_tb_tp_res_05, gt_tb_tp_res_3, hm_tb_tp_res_05, hm_tb_tp_res_3, gt_hm_tb_tp_res_05, gt_hm_tb_tp_res_3):
+	def writeCombinedRes(self, filename, ao_name, hm_tb_res_05, hm_tb_res_3, hm_tp_res_05, hm_tp_res_3, tb_tp_res_05, tb_tp_res_3, hm_tb_tp_res_05, hm_tb_tp_res_3):
 		'''Write result of single detection for combined features.'''
 		
 		with open(filename, 'a') as f:
 			csvwriter = csv.writer(f, delimiter=',')
-			csvwriter.writerow([ao_name, gt_tb_res_05.P, gt_tb_res_05.R, gt_tb_res_05.F, gt_tb_res_3.P, gt_tb_res_3.R, gt_tb_res_3.F, gt_tp_res_05.P, gt_tp_res_05.R, gt_tp_res_05.F, gt_tp_res_3.P, gt_tp_res_3.R, gt_tp_res_3.F, \
-			gt_hm_res_05.P, gt_hm_res_05.R, gt_hm_res_05.F, gt_hm_res_3.P, gt_hm_res_3.R, gt_hm_res_3.F, tb_tp_res_05.P, tb_tp_res_05.R, tb_tp_res_05.F, tb_tp_res_3.P, tb_tp_res_3.R, tb_tp_res_3.F, \
-			hm_tb_res_05.P, hm_tb_res_05.R, hm_tb_res_05.F, hm_tb_res_3.P, hm_tb_res_3.R, hm_tb_res_3.F, hm_tp_res_05.P, hm_tp_res_05.R, hm_tp_res_05.F, hm_tp_res_3.P, hm_tp_res_3.R, hm_tp_res_3.F, \
-			gt_tb_tp_res_05.P, gt_tb_tp_res_05.R, gt_tb_tp_res_05.F, gt_tb_tp_res_3.P, gt_tb_tp_res_3.R, gt_tb_tp_res_3.F, gt_hm_tb_res_05.P, gt_hm_tb_res_05.R, gt_hm_tb_res_05.F, gt_hm_tb_res_3.P, gt_hm_tb_res_3.R, gt_hm_tb_res_3.F, \
-			gt_hm_tp_res_05.P, gt_hm_tp_res_05.R, gt_hm_tp_res_05.F, gt_hm_tp_res_3.P, gt_hm_tp_res_3.R, gt_hm_tp_res_3.F, hm_tb_tp_res_05.P, hm_tb_tp_res_05.R, hm_tb_tp_res_05.F, hm_tb_tp_res_3.P, hm_tb_tp_res_3.R, hm_tb_tp_res_3.F, \
-			gt_hm_tb_tp_res_05.P, gt_hm_tb_tp_res_05.R, gt_hm_tb_tp_res_05.F, gt_hm_tb_tp_res_3.P, gt_hm_tb_tp_res_3.R, gt_hm_tb_tp_res_3.F])
+			csvwriter.writerow([ao_name, hm_tb_res_05.P, hm_tb_res_05.R, hm_tb_res_05.F, hm_tb_res_3.P, hm_tb_res_3.R, hm_tb_res_3.F,\
+			hm_tp_res_05.P, hm_tp_res_05.R, hm_tp_res_05.F, hm_tp_res_3.P, hm_tp_res_3.R, hm_tp_res_3.F, tb_tp_res_05.P, tb_tp_res_05.R, tb_tp_res_05.F, tb_tp_res_3.P, tb_tp_res_3.R, tb_tp_res_3.F, \
+			hm_tb_tp_res_05.P, hm_tb_tp_res_05.R, hm_tb_tp_res_05.F, hm_tb_tp_res_3.P, hm_tb_tp_res_3.R, hm_tb_tp_res_3.F])
+	
+	def removeDuplicates(self, bounds, tol=1.0):		
+		'''Remove duplicates by averaging boundaries located in the tolerance window.'''
+		new_bounds = []
+		bounds = list(set(bounds))
+		bounds.sort()
+		tol_win = int(tol * self.SampleRate / self.stepSize)
 		
-	def writeMergedHeader(self, filename):
-		'''Write header of output files merging individual detections.'''
-		with open(filename, 'a') as f:
-			csvwriter = csv.writer(f, delimiter=',')
-			csvwriter.writerow(['audio', 'merged_tp_05', 'merged_fp_05', 'merged_fn_05', 'merged_P_05', 'merged_R_05', 'merged_F_05', 'merged_AD_05', 'merged_DA_05', 'merged_tp_3', \
-			'merged_fp_3', 'merged_fn_3', 'merged_P_3', 'merged_R_3', 'merged_F_3', 'merged_AD_3', 'merged_DA_3'])
+		bound_idx = 0
+		nBounds = len(bounds)
+		
+		while bound_idx < nBounds:
+			start = bounds[bound_idx]
+			cnt = 1
+			temp = [start]
+			while (bound_idx+cnt < nBounds and (bounds[bound_idx+cnt] - start <= tol_win)):
+				temp.append(bounds[bound_idx+cnt])
+				cnt += 1
 			
-	def writeMergedRes(self, filename, ao_name, merged_res_05, merged_res_3):
-		'''Write results by merging individual detections.'''
-		with open(filename, 'a') as f:
-			csvwriter = csv.writer(f, delimiter=',')
-			csvwriter.writerow([ao_name, merged_res_05.TP, merged_res_05.FP, merged_res_05.FN, merged_res_05.P, merged_res_05.R, merged_res_05.F, merged_res_05.AD, merged_res_05.DA, \
-			merged_res_3.TP, merged_res_3.FP, merged_res_3.FN, merged_res_3.P, merged_res_3.R, merged_res_3.F, merged_res_3.AD, merged_res_3.DA])
-			
+			new_bounds.append(int(np.mean(temp)))
+			bound_idx += cnt
+		
+		# print 'new_bounds', nBounds, len(new_bounds)
+		return new_bounds
+	
+	def selectBounds(self, nc, bounds, thresh=0.5):	
+		'''Select bounds with nc value above thresh.'''
+		# return list(np.array(bounds)[np.where(np.array(nc)>thresh)[0]])	
+		bounds_keep = []
+		nc = normaliseArray(nc)
+		for i, x in enumerate(bounds):
+			if nc[x] >= thresh:
+				bounds_keep.append(x)
+		# print 'bounds_keep', len(bounds), len(bounds_keep)		
+		return bounds_keep
 			
 	def process(self):
 		'''For the aggregated input features, discard a propertion each time as the pairwise distances within the feature space descending. 
@@ -287,43 +304,65 @@
 		tempo_feature_list = [i for i in os.listdir(options.TF) if not i.startswith('.')]
 		tempo_feature_list = ['ti', 'tir']
 		timbre_feature_list = ['mfcc_harmonic']
-		harmonic_feature_list = ['chromagram']
+		harmonic_feature_list = ['chromagram_harmonic']
 
 		gammatone_feature_list = [join(options.GF, f) for f in gammatone_feature_list]
 		timbre_feature_list = [join(options.SF, f) for f in timbre_feature_list]
 		tempo_feature_list = [join(options.TF, f) for f in tempo_feature_list]
 		harmonic_feature_list = [join(options.SF, f) for f in harmonic_feature_list]
 		
-		fobj_list = []
+		
+		# Prepare output files.
+		outfile1 = join(options.OUTPUT, 'individual_novelty.csv')
+		outfile2 = join(options.OUTPUT, 'individual_cnmf.csv')
+		outfile3 = join(options.OUTPUT, 'individual_sf.csv')
+		
+		outfile4 = join(options.OUTPUT, 'combinedFeatures_novelty.csv')
+		outfile5 = join(options.OUTPUT, 'combinedFeatures_cnmf.csv')
+		outfile6 = join(options.OUTPUT, 'combinedFeatures_sf.csv')
 
+		# outfile7 = join(options.OUTPUT, 'combinedSSM_novelty.csv')
+		# 
+		# outfile8 = join(options.OUTPUT, 'combinedBounds_novelty.csv')
+		# outfile9 = join(options.OUTPUT, 'combinedBounds_sf.csv')
+		
+		# self.writeIndividualHeader(outfile1)
+		# self.writeIndividualHeader(outfile2)
+		# self.writeIndividualHeader(outfile3)
+		# 
+		self.writeCombinedHeader(outfile4)			
+		self.writeCombinedHeader(outfile5)
+		self.writeCombinedHeader(outfile6)
+		# self.writeCombinedHeader(outfile7)
+		# self.writeCombinedHeader(outfile8)
+		# self.writeCombinedHeader(outfile9)
+		
 		# For each audio file, load specific features
 		for audio in audio_files:
 			ao = AudioObj()
 			ao.name = splitext(audio)[0]
-			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)
-			# 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)
+
+			# 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)
 
 			gammatone_featureset, timbre_featureset, tempo_featureset, harmonic_featureset = [], [], [], []
-			for feature in gammatone_feature_list:
-				for f in os.listdir(feature):
-					if f[:f.find('_vamp')]==ao.name: 
-						gammatone_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
-						break
-			if len(gammatone_feature_list) > 1:
-				n_frame = np.min([x.shape[0] for x in gammatone_featureset])
-				gammatone_featureset = [x[:n_frame,:] for x in gammatone_featureset]
-				ao.gammatone_features = np.hstack((gammatone_featureset))
-			else:
-				ao.gammatone_features = gammatone_featureset[0]
 			
 			for feature in timbre_feature_list:
 				for f in os.listdir(feature):
 					if f[:f.find('_vamp')]==ao.name: 
-						timbre_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,1:])
+						timbre_featureset.append(np.genfromtxt(join(feature, f), delimiter=',',filling_values=0.0)[:,0:14])
 						break
 			if len(timbre_feature_list) > 1:
 				n_frame = np.min([x.shape[0] for x in timbre_featureset])
@@ -356,23 +395,27 @@
 				ao.harmonic_features = harmonic_featureset[0]
 
 			# Get aggregated features for computing ssm 
-			aggregation_window, aggregation_step = 1,1
-			featureRate = float(self.SampleRate) /self.stepSize
-			pca = PCA(n_components=5)
+			aggregation_window, aggregation_step = 20,10
+			featureRate = float(self.SampleRate) / self.stepSize
+			pca = PCA(n_components=6)
 			
 			# Resample and normalise features
-			step = ao.tempo_features.shape[0]
-			ao.gammatone_features = resample(ao.gammatone_features, step)
-			ao.gammatone_features = normaliseFeature(ao.gammatone_features)
+			# step = ao.tempo_features.shape[0]
+			# ao.timbre_features = resample(ao.timbre_features, step)
+			ao.timbre_features = normaliseFeature(ao.timbre_features)
+			# ao.harmonic_features = resample(ao.harmonic_features, step)
+			ao.harmonic_features = normaliseFeature(ao.harmonic_features)
+			nFrames = np.min([ao.timbre_features.shapes[0], ao.harmonic_features.shapes[0]])
+			ao.timbre_features = ao.timbre_features[:nFrames, :]
+			ao.harmonic_features = ao.harmonic_features[:nFrames, :]
+			ao.tempo_features = normaliseFeature(ao.tempo_features)
+			ao.tempo_features = upSample(ao.tempo_features, nFrames)
+			ao.timestamps = np.array(map(lambda x: x / featureRate, np.arange(0, nFrames)))
+			
+			step = nFrames / 10
 			ao.timbre_features = resample(ao.timbre_features, step)
-			ao.timbre_features = normaliseFeature(ao.timbre_features)
 			ao.harmonic_features = resample(ao.harmonic_features, step)
-			ao.harmonic_features = normaliseFeature(ao.harmonic_features)
-			ao.tempo_features = normaliseFeature(ao.tempo_features)
-			
-			pca.fit(ao.gammatone_features)
-			ao.gammatone_features = pca.transform(ao.gammatone_features)
-			ao.gammatone_ssm = getSSM(ao.gammatone_features)
+			ao.tempo_features = resample(ao.tempo_features, step)
 			
 			pca.fit(ao.tempo_features)
 			ao.tempo_features = pca.transform(ao.tempo_features)
@@ -386,65 +429,24 @@
 			ao.harmonic_features = pca.transform(ao.harmonic_features)
 			ao.harmonic_ssm = getSSM(ao.harmonic_features)
 			
-			ao.ssm_timestamps = np.array(map(lambda x: ao.tempo_timestamps[aggregation_step*x], np.arange(0, ao.gammatone_ssm.shape[0])))
-			
-			audio_list.append(ao)
-			
-		# Prepare output files.
-		outfile1 = join(options.OUTPUT, 'individual_novelty.csv')
-		outfile2 = join(options.OUTPUT, 'individual_foote.csv')
-		outfile3 = join(options.OUTPUT, 'individual_sf.csv')
-		outfile4 = join(options.OUTPUT, 'individual_cnmf.csv')
-		
-		outfile5 = join(options.OUTPUT, 'combined_novelty.csv')
-		outfile6 = join(options.OUTPUT, 'combined_foote.csv')
-		outfile7 = join(options.OUTPUT, 'combined_sf.csv')
-		outfile8 = join(options.OUTPUT, 'combined_cnmf.csv')
-		
-		outfile9 = join(options.OUTPUT, 'individual_merged.csv')
-		
-		self.writeIndividualHeader(outfile1)
-		self.writeIndividualHeader(outfile2)
-		self.writeIndividualHeader(outfile3)
-		self.writeIndividualHeader(outfile4)
-			
-		# self.writeCombinedHeader(outfile5)
-		# self.writeCombinedHeader(outfile6)
-		self.writeCombinedHeader(outfile7)
-		self.writeCombinedHeader(outfile8)
-		
-		self.writeMergedHeader(outfile9)
-		
-		print 'Segmenting using %s method' %options.BOUNDARY
-		for i,ao in enumerate(audio_list):
-			print 'processing: %s' %ao.name
+
 			
 			############################################################################################################################################	
 			# Experiment 1: segmentation using individual features.
-
-			gammatone_novelty, smoothed_gammatone_novelty, gammatone_novelty_idxs = novelty_S.process(ao.gammatone_ssm, self.kernel_size, peak_picker)
-			timbre_novelty, smoothed_timbre_novelty, timbre_novelty_idxs = novelty_S.process(ao.timbre_ssm, self.kernel_size, peak_picker)
-			tempo_novelty, smoothed_tempo_novelty, tempo_novelty_idxs = novelty_S.process(ao.tempo_ssm, self.kernel_size, peak_picker)
-			harmonic_novelty, smoothed_harmonic_novelty, harmonic_novelty_idxs = novelty_S.process(ao.harmonic_ssm, self.kernel_size, peak_picker)
+			
+			timbre_novelty, smoothed_timbre_novelty, timbre_novelty_idxs = novelty_S.process(ao.timbre_ssm, peak_picker, self.kernel_size)
+			tempo_novelty, smoothed_tempo_novelty, tempo_novelty_idxs = novelty_S.process(ao.tempo_ssm, peak_picker, self.kernel_size)
+			harmonic_novelty, smoothed_harmonic_novelty, harmonic_novelty_idxs = novelty_S.process(ao.harmonic_ssm, peak_picker, self.kernel_size)
 						
-			gammatone_cnmf_idxs = cnmf_S.segmentation(ao.gammatone_features, rank=rank, R=R, h=h, niter=300)
-			timbre_cnmf_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)
-			tempo_cnmf_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)
-			harmonic_cnmf_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)
+			timbre_cnmf_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)[-1]
+			tempo_cnmf_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)[-1]
+			harmonic_cnmf_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)[-1]
 			
-			gammatone_foote_idxs = foote_S.segmentation(ao.gammatone_features, M=M, Mg=Mg, L=L)
-			timbre_foote_idxs = foote_S.segmentation(ao.timbre_features, M=M, Mg=Mg, L=L)
-			tempo_foote_idxs = foote_S.segmentation(ao.tempo_features, M=M, Mg=Mg, L=L)
-			harmonic_foote_idxs = foote_S.segmentation(ao.harmonic_features, M=M, Mg=Mg, L=L)
-						
-			gammatone_sf_idxs = sf_S.segmentation(ao.gammatone_features)
-			timbre_sf_idxs = sf_S.segmentation(ao.timbre_features)
-			tempo_sf_idxs = sf_S.segmentation(ao.tempo_features)
-			harmonic_sf_idxs = sf_S.segmentation(ao.harmonic_features)
+			timbre_sf_nc, timbre_sf_idxs = sf_S.segmentation(ao.timbre_features)
+			tempo_sf_nc, tempo_sf_idxs = sf_S.segmentation(ao.tempo_features)
+			harmonic_sf_nc, harmonic_sf_idxs = sf_S.segmentation(ao.harmonic_features)
 				
 			# Evaluate and write results.
-			gt_novelty_05 = self.pairwiseF(ao.gt, gammatone_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_novelty_3 = self.pairwiseF(ao.gt, gammatone_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			harmonic_novelty_05 = self.pairwiseF(ao.gt, harmonic_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			harmonic_novelty_3 = self.pairwiseF(ao.gt, harmonic_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			tempo_novelty_05 = self.pairwiseF(ao.gt, tempo_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
@@ -452,227 +454,170 @@
 			timbre_novelty_05 = self.pairwiseF(ao.gt, timbre_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			timbre_novelty_3 = self.pairwiseF(ao.gt, timbre_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			
-			gt_cnmf_05 = self.pairwiseF(ao.gt, gammatone_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_cnmf_3 = self.pairwiseF(ao.gt, gammatone_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			harmonic_cnmf_05 = self.pairwiseF(ao.gt, harmonic_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			harmonic_cnmf_3 = self.pairwiseF(ao.gt, harmonic_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			tempo_cnmf_05 = self.pairwiseF(ao.gt, tempo_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			tempo_cnmf_3 = self.pairwiseF(ao.gt, tempo_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			timbre_cnmf_05 = self.pairwiseF(ao.gt, timbre_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			timbre_cnmf_3 = self.pairwiseF(ao.gt, timbre_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-
-			gt_sf_05 = self.pairwiseF(ao.gt, gammatone_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_sf_3 = self.pairwiseF(ao.gt, gammatone_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			
 			harmonic_sf_05 = self.pairwiseF(ao.gt, harmonic_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			harmonic_sf_3 = self.pairwiseF(ao.gt, harmonic_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			tempo_sf_05 = self.pairwiseF(ao.gt, tempo_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			tempo_sf_3 = self.pairwiseF(ao.gt, tempo_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			timbre_sf_05 = self.pairwiseF(ao.gt, timbre_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			timbre_sf_3 = self.pairwiseF(ao.gt, timbre_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-
-			gt_foote_05 = self.pairwiseF(ao.gt, gammatone_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_foote_3 = self.pairwiseF(ao.gt, gammatone_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			harmonic_foote_05 = self.pairwiseF(ao.gt, harmonic_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			harmonic_foote_3 = self.pairwiseF(ao.gt, harmonic_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			tempo_foote_05 = self.pairwiseF(ao.gt, tempo_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			tempo_foote_3 = self.pairwiseF(ao.gt, tempo_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			timbre_foote_05 = self.pairwiseF(ao.gt, timbre_foote_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			timbre_foote_3 = self.pairwiseF(ao.gt, timbre_foote_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			
-			self.writeIndividualRes(outfile1, ao.name, gt_novelty_05, gt_novelty_3, harmonic_novelty_05, harmonic_novelty_3, tempo_novelty_05, tempo_novelty_3, timbre_novelty_05, timbre_novelty_3)
-			self.writeIndividualRes(outfile2, ao.name, gt_cnmf_05, gt_cnmf_3, harmonic_cnmf_05, harmonic_cnmf_3, tempo_cnmf_05, tempo_cnmf_3, timbre_cnmf_05, timbre_cnmf_3)
-			self.writeIndividualRes(outfile3, ao.name, gt_sf_05, gt_sf_3, harmonic_sf_05, harmonic_sf_3, tempo_sf_05, tempo_sf_3, timbre_sf_05, timbre_sf_3)
-			self.writeIndividualRes(outfile4, ao.name, gt_foote_05, gt_foote_3, harmonic_foote_05, harmonic_foote_3, tempo_foote_05, tempo_foote_3, timbre_foote_05, timbre_foote_3)
+			self.writeIndividualRes(outfile1, ao.name, harmonic_novelty_05, harmonic_novelty_3, tempo_novelty_05, tempo_novelty_3, timbre_novelty_05, timbre_novelty_3)
+			self.writeIndividualRes(outfile2, ao.name, harmonic_cnmf_05, harmonic_cnmf_3, tempo_cnmf_05, tempo_cnmf_3, timbre_cnmf_05, timbre_cnmf_3)
+			self.writeIndividualRes(outfile3, ao.name, harmonic_sf_05, harmonic_sf_3, tempo_sf_05, tempo_sf_3, timbre_sf_05, timbre_sf_3)
 			
 			
 			############################################################################################################################################
 			# Experiment 2: segmentation using combined features.
 			
 			# Dumping features.			
-			gt_hm = np.hstack([ao.gammatone_features, ao.harmonic_features])
-			gt_tb = np.hstack([ao.gammatone_features, ao.timbre_features])
-			gt_tp = np.hstack([ao.gammatone_features, ao.tempo_features])
 			hm_tb = np.hstack([ao.harmonic_features, ao.timbre_features])
 			hm_tp = np.hstack([ao.harmonic_features, ao.tempo_features])
 			tb_tp = np.hstack([ao.timbre_features, ao.tempo_features])
-			gt_hm_tb = np.hstack([ao.gammatone_features, ao.harmonic_features, ao.timbre_features])
-			gt_hm_tp = np.hstack([ao.gammatone_features, ao.harmonic_features, ao.tempo_features])
-			gt_tb_tp = np.hstack([ao.gammatone_features, ao.timbre_features, ao.tempo_features])
 			hm_tb_tp = np.hstack([ao.harmonic_features, ao.timbre_features, ao.tempo_features])
-			gt_hm_tb_tp = np.hstack([ao.gammatone_features, ao.harmonic_features, ao.timbre_features, ao.tempo_features])
+			
+			hm_tb_feature_ssm = getSSM(hm_tb)
+			hm_tp_feature_ssm = getSSM(hm_tp)
+			tb_tp_feature_ssm = getSSM(tb_tp)
+			hm_tb_tp_feature_ssm = getSSM(hm_tb_tp)
 			
 			# Evaluting and writing results.
-			gt_hm_sf_idxs = sf_S.segmentation(gt_hm)
-			gt_tb_sf_idxs = sf_S.segmentation(gt_tb)
-			gt_tp_sf_idxs = sf_S.segmentation(gt_tp)
-			hm_tb_sf_idxs = sf_S.segmentation(hm_tb)
-			hm_tp_sf_idxs = sf_S.segmentation(hm_tp)
-			tb_tp_sf_idxs = sf_S.segmentation(tb_tp)
-			gt_hm_tb_sf_idxs = sf_S.segmentation(gt_hm_tb)
-			gt_hm_tp_sf_idxs = sf_S.segmentation(gt_hm_tp)
-			gt_tb_tp_sf_idxs = sf_S.segmentation(gt_tb_tp)
-			hm_tb_tp_sf_idxs = sf_S.segmentation(hm_tb_tp)
-			gt_hm_tb_tp_sf_idxs = sf_S.segmentation(gt_hm_tb_tp)
+			hm_tb_novelty_idxs = novelty_S.process(hm_tb_feature_ssm)[-1]
+			hm_tp_novelty_idxs = novelty_S.process(hm_tp_feature_ssm)[-1]
+			tb_tp_novelty_idxs = novelty_S.process(tb_tp_feature_ssm)[-1]
+			hm_tb_tp_novelty_idxs = novelty_S.process(hm_tb_tp_feature_ssm)[-1]
 			
-			gt_hm_cnmf_idxs = cnmf_S.segmentation(gt_hm, rank=4, R=R, h=h, niter=300)
-			gt_tb_cnmf_idxs = cnmf_S.segmentation(gt_tb, rank=4, R=R, h=h, niter=300)
-			gt_tp_cnmf_idxs = cnmf_S.segmentation(gt_tp, rank=4, R=R, h=h, niter=300)
-			hm_tb_cnmf_idxs = cnmf_S.segmentation(hm_tb, rank=4, R=R, h=h, niter=300)
-			hm_tp_cnmf_idxs = cnmf_S.segmentation(hm_tp, rank=4, R=R, h=h, niter=300)
-			tb_tp_cnmf_idxs = cnmf_S.segmentation(tb_tp, rank=4, R=R, h=h, niter=300)
-			gt_hm_tb_cnmf_idxs = cnmf_S.segmentation(gt_hm_tb, rank=6, R=R, h=h, niter=300)
-			gt_hm_tp_cnmf_idxs = cnmf_S.segmentation(gt_hm_tp, rank=6, R=R, h=h, niter=300)
-			gt_tb_tp_cnmf_idxs = cnmf_S.segmentation(gt_tb_tp, rank=6, R=R, h=h, niter=300)
-			hm_tb_tp_cnmf_idxs = cnmf_S.segmentation(hm_tb_tp, rank=6, R=R, h=h, niter=300)
-			gt_hm_tb_tp_cnmf_idxs = cnmf_S.segmentation(gt_hm_tb_tp, rank=8, R=R, h=h, niter=300)
+			hm_tb_sf_idxs = sf_S.segmentation(hm_tb)[-1]
+			hm_tp_sf_idxs = sf_S.segmentation(hm_tp)[-1]
+			tb_tp_sf_idxs = sf_S.segmentation(tb_tp)[-1]
+			hm_tb_tp_sf_idxs = sf_S.segmentation(hm_tb_tp)[-1]
 			
-			gt_hm_sf_05 = self.pairwiseF(ao.gt, gt_hm_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_sf_05 = self.pairwiseF(ao.gt, gt_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tp_sf_05 = self.pairwiseF(ao.gt, gt_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			hm_tb_cnmf_idxs = cnmf_S.segmentation(hm_tb, rank=4, R=R, h=h, niter=300)[-1]
+			hm_tp_cnmf_idxs = cnmf_S.segmentation(hm_tp, rank=4, R=R, h=h, niter=300)[-1]
+			tb_tp_cnmf_idxs = cnmf_S.segmentation(tb_tp, rank=4, R=R, h=h, niter=300)[-1]
+			hm_tb_tp_cnmf_idxs = cnmf_S.segmentation(hm_tb_tp, rank=6, R=R, h=h, niter=300)[-1]
+			
+			hm_tb_novelty_05 = self.pairwiseF(ao.gt, hm_tb_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			hm_tp_novelty_05 = self.pairwiseF(ao.gt, hm_tp_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			tb_tp_novelty_05 = self.pairwiseF(ao.gt, tb_tp_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			hm_tb_tp_novelty_05 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			
+			hm_tb_novelty_3 = self.pairwiseF(ao.gt, hm_tb_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			hm_tp_novelty_3 = self.pairwiseF(ao.gt, hm_tp_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			tb_tp_novelty_3 = self.pairwiseF(ao.gt, tb_tp_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			hm_tb_tp_novelty_3 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+					
 			hm_tb_sf_05 = self.pairwiseF(ao.gt, hm_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tp_sf_05 = self.pairwiseF(ao.gt, hm_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			tb_tp_sf_05 = self.pairwiseF(ao.gt, tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_sf_05 = self.pairwiseF(ao.gt, gt_hm_tb_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tp_sf_05 = self.pairwiseF(ao.gt, gt_hm_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_tp_sf_05 = self.pairwiseF(ao.gt, gt_tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tb_tp_sf_05 = self.pairwiseF(ao.gt, hm_tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_tp_sf_05 = self.pairwiseF(ao.gt, gt_hm_tb_tp_sf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			
-			gt_hm_sf_3 = self.pairwiseF(ao.gt, gt_hm_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_sf_3 = self.pairwiseF(ao.gt, gt_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tp_sf_3 = self.pairwiseF(ao.gt, gt_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tb_sf_3 = self.pairwiseF(ao.gt, hm_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tp_sf_3 = self.pairwiseF(ao.gt, hm_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			tb_tp_sf_3 = self.pairwiseF(ao.gt, tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_sf_3 = self.pairwiseF(ao.gt, gt_hm_tb_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tp_sf_3 = self.pairwiseF(ao.gt, gt_hm_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_tp_sf_3 = self.pairwiseF(ao.gt, gt_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tb_tp_sf_3 = self.pairwiseF(ao.gt, hm_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_tp_sf_3 = self.pairwiseF(ao.gt, gt_hm_tb_tp_sf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-
-			gt_hm_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_cnmf_05 = self.pairwiseF(ao.gt, gt_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			
 			hm_tb_cnmf_05 = self.pairwiseF(ao.gt, hm_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tp_cnmf_05 = self.pairwiseF(ao.gt, hm_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			tb_tp_cnmf_05 = self.pairwiseF(ao.gt, tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_tb_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tb_tp_cnmf_05 = self.pairwiseF(ao.gt, hm_tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_tp_cnmf_05 = self.pairwiseF(ao.gt, gt_hm_tb_tp_cnmf_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
 			
-			gt_hm_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_cnmf_3 = self.pairwiseF(ao.gt, gt_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tb_cnmf_3 = self.pairwiseF(ao.gt, hm_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tp_cnmf_3 = self.pairwiseF(ao.gt, hm_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			tb_tp_cnmf_3 = self.pairwiseF(ao.gt, tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_tb_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 			hm_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, hm_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
-			gt_hm_tb_tp_cnmf_3 = self.pairwiseF(ao.gt, gt_hm_tb_tp_cnmf_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
 					
-			self.writeCombinedRes(outfile7, ao.name, gt_hm_sf_05, gt_hm_sf_3, gt_tb_sf_05, gt_tb_sf_3, gt_tp_sf_05, gt_tp_sf_3, hm_tb_sf_05, hm_tb_sf_3, hm_tp_sf_05, hm_tp_sf_3, tb_tp_sf_05, tb_tp_sf_3,\
-			gt_hm_tb_sf_05, gt_hm_tb_sf_3, gt_hm_tp_sf_05, gt_hm_tp_sf_3, gt_tb_tp_sf_05, gt_tb_tp_sf_3, hm_tb_tp_sf_05, hm_tb_tp_sf_3, gt_hm_tb_tp_sf_05, gt_hm_tb_tp_sf_3)
-
-			self.writeCombinedRes(outfile8, ao.name, gt_hm_cnmf_05, gt_hm_cnmf_3, gt_tb_cnmf_05, gt_tb_cnmf_3, gt_tp_cnmf_05, gt_tp_cnmf_3, hm_tb_cnmf_05, hm_tb_cnmf_3, hm_tp_cnmf_05, hm_tp_cnmf_3, tb_tp_cnmf_05, tb_tp_cnmf_3,\
-			gt_hm_tb_cnmf_05, gt_hm_tb_cnmf_3, gt_hm_tp_cnmf_05, gt_hm_tp_cnmf_3, gt_tb_tp_cnmf_05, gt_tb_tp_cnmf_3, hm_tb_tp_cnmf_05, hm_tb_tp_cnmf_3, gt_hm_tb_tp_cnmf_05, gt_hm_tb_tp_cnmf_3)
 			
-			############################################################################################################################################
-			# Experiment 3: Pruning boundaries detected by individual boundary algorithms.
+			self.writeCombinedRes(outfile4, ao.name, hm_tb_novelty_05, hm_tb_novelty_3, hm_tp_novelty_05, hm_tp_novelty_3, tb_tp_novelty_05, tb_tp_novelty_3, hm_tb_tp_novelty_05, hm_tb_tp_novelty_3)
+			self.writeCombinedRes(outfile5, ao.name, hm_tb_cnmf_05, hm_tb_cnmf_3, hm_tp_cnmf_05, hm_tp_cnmf_3, tb_tp_cnmf_05, tb_tp_cnmf_3, hm_tb_tp_cnmf_05, hm_tb_tp_cnmf_3)
+			self.writeCombinedRes(outfile6, ao.name, hm_tb_sf_05, hm_tb_sf_3, hm_tp_sf_05, hm_tp_sf_3, tb_tp_sf_05, tb_tp_sf_3, hm_tb_tp_sf_05, hm_tb_tp_sf_3)
 			
-			# Use different boundary methods for different features
-			gammatone_idxs, harmonic_idxs, timbre_idxs, tempo_idxs = gammatone_sf_idxs, harmonic_sf_idxs, timbre_sf_idxs, tempo_sf_idxs
-			bound_candidates = list(gammatone_idxs) + list(harmonic_idxs) + list(timbre_idxs) + list(tempo_idxs)
-			bound_candidates.sort()
 			
-			nBounds = len(bound_candidates)
-			final_idxs = []
-			idx = 0
-			tol = 10 # tolerance window of merging boundary scores
-			while idx < nBounds:
-				temp = [bound_candidates[idx]]
-				pos = [idx]
-				idx += 1
-				while (idx + tol < nBounds and np.max(bound_candidates[idx: idx+tol]) > 0):
-					temp += [bound_candidates[idx+delta] for delta in xrange(tol) if (bound_candidates[idx]+delta in bound_candidates)]
-					pos += [idx+delta for delta in xrange(tol) if (bound_candidates[idx]+delta in bound_candidates)]
-					idx += tol
-				if len(temp) == 1:
-					final_idxs.append(temp[0])
-				else:
-					final_idxs.append(int(np.rint(np.mean(temp))))
+			# ############################################################################################################################################
+			# # Experiment 3: late fusion -- segmentation using combined ssms.
+			# 
+			# hm_tb_ssm = self.lin * ao.harmonic_ssm + (1-self.lin) * ao.timbre_ssm
+			# hm_tp_ssm = self.lin * ao.harmonic_ssm + (1-self.lin) * ao.tempo_ssm
+			# tb_tp_ssm = self.lin * ao.timbre_ssm + (1-self.lin) * ao.tempo_ssm
+			# hm_tb_tp_ssm = (ao.harmonic_ssm + ao.timbre_ssm + ao.tempo_ssm) / 3.0
+			# 
+			# hm_tb_ssm_novelty_idxs = novelty_S.process(hm_tb_ssm)[-1]
+			# hm_tp_ssm_novelty_idxs = novelty_S.process(hm_tp_ssm)[-1]
+			# tb_tp_ssm_novelty_idxs = novelty_S.process(tb_tp_ssm)[-1]
+			# hm_tb_tp_ssm_novelty_idxs = novelty_S.process(hm_tb_tp_ssm)[-1]
+			# 
+			# hm_tb_ssm_novelty_05 = self.pairwiseF(ao.gt, hm_tb_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tp_ssm_novelty_05 = self.pairwiseF(ao.gt, hm_tp_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# tb_tp_ssm_novelty_05 = self.pairwiseF(ao.gt, tb_tp_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tb_tp_ssm_novelty_05 = self.pairwiseF(ao.gt, hm_tb_tp_ssm_novelty_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# 
+			# hm_tb_ssm_novelty_3 = self.pairwiseF(ao.gt, hm_tb_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tp_ssm_novelty_3 = self.pairwiseF(ao.gt, hm_tp_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# tb_tp_ssm_novelty_3 = self.pairwiseF(ao.gt, tb_tp_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tb_tp_ssm_novelty_3 = self.pairwiseF(ao.gt, hm_tb_tp_ssm_novelty_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# 
+			# self.writeCombinedRes(outfile7, ao.name, hm_tb_ssm_novelty_05, hm_tb_ssm_novelty_3, hm_tp_ssm_novelty_05, hm_tp_ssm_novelty_3, tb_tp_ssm_novelty_05, tb_tp_ssm_novelty_3, hm_tb_tp_ssm_novelty_05, hm_tb_tp_ssm_novelty_3)
 			
-			merged_05 = self.pairwiseF(ao.gt, final_idxs, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
-			merged_3 = self.pairwiseF(ao.gt, final_idxs, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# ############################################################################################################################################
+			# # Experiment 4: late fusion -- segmentation using combined boundaries.
+			# hm_novelty_bounds = self.selectBounds(smoothed_harmonic_novelty, harmonic_novelty_idxs, self.confidence_threshold)
+			# tb_novelty_bounds = self.selectBounds(smoothed_timbre_novelty, timbre_novelty_idxs, self.confidence_threshold)
+			# tp_novelty_bounds = self.selectBounds(smoothed_tempo_novelty, timbre_novelty_idxs, self.confidence_threshold)
+			# 
+			# hm_tb_novelty_bounds = hm_novelty_bounds + tb_novelty_bounds
+			# hm_tp_novelty_bounds = hm_novelty_bounds + tp_novelty_bounds
+			# tb_tp_novelty_bounds = tb_novelty_bounds + tp_novelty_bounds
+			# hm_tb_tp_novelty_bounds = hm_novelty_bounds + tb_novelty_bounds + tp_novelty_bounds
+			# 
+			# hm_tb_novelty_bounds = self.removeDuplicates(hm_tb_novelty_bounds, tol=1.0)
+			# hm_tp_novelty_bounds = self.removeDuplicates(hm_tp_novelty_bounds, tol=1.0)
+			# tb_tp_novelty_bounds = self.removeDuplicates(tb_tp_novelty_bounds, tol=1.0)
+			# hm_tb_tp_novelty_bounds = self.removeDuplicates(hm_tb_tp_novelty_bounds, tol=1.0)
+			# 
+			# hm_sf_bounds = self.selectBounds(harmonic_sf_nc, harmonic_sf_idxs, self.confidence_threshold)
+			# tb_sf_bounds = self.selectBounds(timbre_sf_nc, timbre_sf_idxs, self.confidence_threshold)
+			# tp_sf_bounds = self.selectBounds(tempo_sf_nc, tempo_sf_idxs, self.confidence_threshold)
+			# 
+			# hm_tb_sf_bounds = hm_sf_bounds + tb_sf_bounds
+			# hm_tp_sf_bounds = hm_sf_bounds + tp_sf_bounds
+			# tb_tp_sf_bounds = tb_sf_bounds + tp_sf_bounds
+			# hm_tb_tp_sf_bounds = hm_sf_bounds + tb_sf_bounds + tp_sf_bounds
+			# 
+			# hm_tb_sf_bounds = self.removeDuplicates(hm_tb_sf_bounds, tol=1.0)
+			# hm_tp_sf_bounds = self.removeDuplicates(hm_tp_sf_bounds, tol=1.0)
+			# tb_tp_sf_bounds = self.removeDuplicates(tb_tp_sf_bounds, tol=1.0)
+			# hm_tb_tp_sf_bounds = self.removeDuplicates(hm_tb_tp_sf_bounds, tol=1.0)
+			# 
+			# 
+			# hm_tb_novelty_bounds_05 = self.pairwiseF(ao.gt, hm_tb_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tp_novelty_bounds_05 = self.pairwiseF(ao.gt, hm_tp_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# tb_tp_novelty_bounds_05 = self.pairwiseF(ao.gt, tb_tp_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tb_tp_novelty_bounds_05 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# 
+			# hm_tb_sf_bounds_05 = self.pairwiseF(ao.gt, hm_tb_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tp_sf_bounds_05 = self.pairwiseF(ao.gt, hm_tp_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# tb_tp_sf_bounds_05 = self.pairwiseF(ao.gt, tb_tp_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tb_tp_sf_bounds_05 = self.pairwiseF(ao.gt, hm_tb_tp_sf_bounds, tolerance=0.5, combine=1.0, idx2time=ao.ssm_timestamps)
+			# 
+			# hm_tb_novelty_bounds_3 = self.pairwiseF(ao.gt, hm_tb_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tp_novelty_bounds_3 = self.pairwiseF(ao.gt, hm_tp_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# tb_tp_novelty_bounds_3 = self.pairwiseF(ao.gt, tb_tp_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tb_tp_novelty_bounds_3 = self.pairwiseF(ao.gt, hm_tb_tp_novelty_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# 
+			# hm_tb_sf_bounds_3 = self.pairwiseF(ao.gt, hm_tb_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tp_sf_bounds_3 = self.pairwiseF(ao.gt, hm_tp_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# tb_tp_sf_bounds_3 = self.pairwiseF(ao.gt, tb_tp_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# hm_tb_tp_sf_bounds_3 = self.pairwiseF(ao.gt, hm_tb_tp_sf_bounds, tolerance=3, combine=1.0, idx2time=ao.ssm_timestamps)
+			# 
+			# self.writeCombinedRes(outfile8, ao.name, hm_tb_novelty_bounds_05, hm_tb_novelty_bounds_3, hm_tp_novelty_bounds_05, hm_tp_novelty_bounds_3, tb_tp_novelty_bounds_05, tb_tp_novelty_bounds_3, hm_tb_tp_novelty_bounds_05, hm_tb_tp_novelty_bounds_3)
+			# self.writeCombinedRes(outfile9, ao.name, hm_tb_sf_bounds_05, hm_tb_sf_bounds_3, hm_tp_sf_bounds_05, hm_tp_sf_bounds_3, tb_tp_sf_bounds_05, tb_tp_sf_bounds_3, hm_tb_tp_sf_bounds_05, hm_tb_tp_sf_bounds_3)
 			
-			self.writeMergedRes(outfile9, ao.name, merged_05, merged_3)
-			
-			# if options.BOUNDARY == 'novelty':
-			# 	gammatone_novelty, smoothed_gammatone_novelty, gammatone_bound_idxs = novelty_S.process(ao.gammatone_ssm, self.kernel_size, peak_picker)
-			# 	timbre_novelty, smoothed_timbre_novelty, timbre_bound_idxs = novelty_S.process(ao.timbre_ssm, self.kernel_size, peak_picker)
-			# 	tempo_novelty, smoothed_harmonic_novelty, tempo_bound_idxs = novelty_S.process(ao.tempo_ssm, self.kernel_size, peak_picker)
-			# 	harmonic_novelty, smoothed_tempo_novelty, harmonic_bound_idxs = novelty_S.process(ao.harmonic_ssm, self.kernel_size, peak_picker)
-			# 				
-			# if options.BOUNDARY == 'cnmf':
-			# 	gammatone_cnmf_idxs = cnmf_S.segmentation(ao.gammatone_features, rank=rank, R=R, h=8, niter=300)
-			# 	timbre_cnmf_idxs = cnmf_S.segmentation(ao.timbre_features, rank=rank, R=R, h=h, niter=300)
-			# 	tempo_cnmf_idxs = cnmf_S.segmentation(ao.tempo_features, rank=rank, R=R, h=h, niter=300)
-			# 	harmonic_cnmf_idxs = cnmf_S.segmentation(ao.harmonic_features, rank=rank, R=R, h=h, niter=300)
-			# 	
-			# if options.BOUNDARY == 'foote':
-			# 	gammatone_foote_idxs = foote_S.segmentation(ao.gammatone_features, M=M, Mg=Mg, L=L)
-			# 	timbre_foote_idxs = foote_S.segmentation(ao.timbre_features, M=M, Mg=Mg, L=L)
-			# 	tempo_foote_idxs = foote_S.segmentation(ao.tempo_features, M=M, Mg=Mg, L=L)
-			# 	harmonic_foote_idxs = foote_S.segmentation(ao.harmonic_features, M=M, Mg=Mg, L=L)
-			# 
-			# if options.BOUNDARY == 'sf':
-			# 	gammatone_sf_idxs = sf_S.segmentation(ao.gammatone_features)
-			# 	timbre_sf_idxs = sf_S.segmentation(ao.timbre_features)
-			# 	tempo_sf_idxs = sf_S.segmentation(ao.tempo_features)
-			# 	harmonic_sf_idxs = sf_S.segmentation(ao.harmonic_features)
-			# 
-			# gammatone_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_novelty_peaks]
-			# timbre_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_novelty_peaks]
-			# harmonic_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_novelty_peaks]
-			# tempo_novelty_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_novelty_peaks]
-			# 
-			# gammatone_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_cnmf_peaks]
-			# timbre_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_cnmf_peaks]
-			# harmonic_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_cnmf_peaks]
-			# tempo_cnmf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_cnmf_peaks]
-			# 
-			# gammatone_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_sf_peaks]
-			# timbre_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_sf_peaks]
-			# harmonic_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_sf_peaks]
-			# tempo_sf_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_sf_peaks]
-			# 
-			# gammatone_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in gammatone_foote_peaks]
-			# timbre_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in timbre_foote_peaks]
-			# harmonic_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in harmonic_foote_peaks]
-			# tempo_foote_detection = [0.0] + [ao.ssm_timestamps[int(np.rint(i))] for i in tempo_foote_peaks]
-			# 
-			# # Experiment 2: Trying combined features using the best boundary retrieval method
-			# ao_featureset = [ao.gammatone_features, ao.harmonic_features, ao.timbre_features, ao.tempo_features]
-			# feature_sel = [int(x) for x in options.FEATURES if x.isdigit()]
-			# fused_featureset = [ao_featureset[i] for i in feature_sel]
-			
-			# if options.LABEL == 'fmc2d':
-			# 	gammatone_fmc2d_labels = fmc2d_S.compute_similarity(gammatone_bound_idxs, xmeans=True, N=N)
-			# 	timbre_fmc2d_labels = fmc2d_S.compute_similarity(timbre_bound_idxs, xmeans=True, N=N)
-			# 	tempo_fmc2d_labels = fmc2d_S.compute_similarity(tempo_bound_idxs, xmeans=True, N=N)
-			# 	harmonic_fmc2d_labels = fmc2d_S.compute_similarity(harmonic_bound_idxs, xmeans=True, N=N)
-			# 
-			# if options.LABEL == 'cnmf':	
-			# 	gammatone_cnmf_labels = cnmf_S.compute_labels(gammatone_bound_idxs, est_bound_idxs, nFrames)
-			# 	timbre_cnmf_labels = cnmf_S.compute_labels(timbre_bound_idxs, est_bound_idxs, nFrames)
-			# 	tempo_cnmf_labels = cnmf_S.compute_labels(tempo_bound_idxs, est_bound_idxs, nFrames)
-			# 	harmonic_cnmf_labels = cnmf_S.compute_labels(harmonic_bound_idxs, est_bound_idxs, nFrames)
-			# 	
-			# 
-						
 
 
 def main():
--- a/annotation/qupujicheng_annotation_30_3/10hongniang02.csv	Fri Aug 21 10:15:29 2015 +0100
+++ b/annotation/qupujicheng_annotation_30_3/10hongniang02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -1,71 +1,36 @@
-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
+0.000000000,1.1
+11.540317460,a
+19.493151927,New Point
+25.353356009,1.2
+34.527959183,1.2
+38.995918367,New Point
+46.393469387,a
+63.249682539,1.3
+66.378979591,1.3
+74.889795918,New Point
+80.135215419,1.4
+87.489455782,2.1
+94.923174603,a
+105.180793650,2.2
+112.015895691,2.4
+135.116916099,New Point
+140.312380952,New Point
+144.486167800,New Point
+155.480816326,a
+170.034149659,1.4
+184.598639455,New Point
+191.750385487,New Point
+206.228027210,New Point
+211.858866213,sp
+217.907664399,New Point
+223.108934240,New Point
+230.539319727,New Point
+233.424399092,New Point
+250.618775510,New Point
+254.158798185,3.1
+257.590566893,New Point
+260.736870748,a
+273.745850340,New Point
+284.154195011,New Point
+299.371111111,3.2
+304.274285714,end
--- a/annotation/qupujicheng_annotation_30_3/1bawangbieji02.csv	Fri Aug 21 10:15:29 2015 +0100
+++ b/annotation/qupujicheng_annotation_30_3/1bawangbieji02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -1,21 +1,27 @@
 0.285170068,s
 10.762448979,New Point
 18.982312925,New Point
+25.321360544,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
+85.867052154,1.1
+98.227256235,1.2
 123.771428571,a
 140.114285714,New Point
 147.073469387,a
 156.595374149,New Point
 165.535056689,New Point
+175.533537414,3.1
 186.224036281,New Point
 195.330612244,New Point
 205.403718820,New Point
 216.783673469,New Point
+229.119229024,1.4
+236.361020408,2.2
+251.824535147,2.4
 256.946938775,New Point
 256.975238095,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_4/10hongniang01.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/10hongniang02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -0,0 +1,36 @@
+0.000000000,1.1
+11.540317460,a
+19.493151927,New Point
+25.353356009,1.2
+34.527959183,1.2
+38.995918367,New Point
+46.393469387,a
+63.249682539,1.3
+66.378979591,1.3
+74.889795918,New Point
+80.135215419,1.4
+87.489455782,2.1
+94.923174603,a
+105.180793650,2.2
+112.015895691,2.4
+135.116916099,New Point
+140.312380952,New Point
+144.486167800,New Point
+155.480816326,a
+170.034149659,1.4
+184.598639455,New Point
+191.750385487,New Point
+206.228027210,New Point
+211.858866213,sp
+217.907664399,New Point
+223.108934240,New Point
+230.539319727,New Point
+233.424399092,New Point
+250.618775510,New Point
+254.158798185,3.1
+257.590566893,New Point
+260.736870748,a
+273.745850340,New Point
+284.154195011,New Point
+299.371111111,3.2
+304.274285714,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_4/10hongniang04.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/1bawangbieji02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -0,0 +1,36 @@
+0.285170068,s
+10.762448979,New Point
+18.982312925,New Point
+25.321360544,New Point
+32.449886621,New Point
+39.787755102,a
+51.362539682,s
+58.165986394,New Point
+64.029070294,3.3
+77.453061224,New Point
+82.220408163,New Point
+85.867052154,1.1
+98.227256235,1.2
+104.219659863,4.1
+111.198843537,4.2
+117.071428571,4.3
+123.771428571,a
+134.351065759,4.4
+140.114285714,New Point
+145.457233560,5.1
+151.831043083,5.2
+156.595374149,New Point
+165.535056689,New Point
+170.293718820,5.3
+175.533537414,3.1
+186.224036281,New Point
+189.826099773,5.4
+195.330612244,New Point
+197.952766439,6.1
+205.403718820,New Point
+216.783673469,New Point
+229.119229024,1.4
+236.361020408,2.2
+251.824535147,2.4
+256.946938775,New Point
+256.975238095,end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/annotation/qupujicheng_annotation_30_4/1yuzhoufeng01.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/1yuzhoufeng02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/2kongchengji_xipimanban.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/2lilingbei.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/2wenzhaoguan.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/2xucepaocheng.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/3dayushajia_xipikuaisanyan.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/3nuqijie0215-0517.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/4qingguance.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/4yaoqi.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/5suolinnang.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/6liuyuexue.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/6zhuofangcao_erhuangmanbanyuanban.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/6zhuofangcao_xipimanban.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/7jinyunu01.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/7jinyunu04.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/7jinyunu06.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/7longfengchengxiang.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/7sangyuanjizi.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/8zuozhaidaoma01.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/8zuozhaidaoma02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/9shangtiantai_erhaungkuaisanyan.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/9shangtiantai_erhuangsanyan.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/9shangtiantai_erhuangyuanban.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/9tiannusanhua01.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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_4/9tiannusanhua02.csv	Wed Dec 09 16:27:10 2015 +0000
@@ -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	Fri Aug 21 10:15:29 2015 +0100
+++ b/cnmf.py	Wed Dec 09 16:27:10 2015 +0000
@@ -138,13 +138,13 @@
 	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)
+				if CNMF: F, G0 = cnmf(X, rank, niter=niter)
+				else: F, G0 = nmf(X, rank, niter=niter)
 			except:
-				return np.empty(0), [1]
+				return np.empty(0), np.empty(0), [1]
 
 			# Filter G
-			G = filter_activation_matrix(G.T, R)
+			G = filter_activation_matrix(G0.T, R)
 			if bound_idxs is None:
 				bound_idxs = np.where(np.diff(G) != 0)[0] + 1
 
@@ -153,5 +153,8 @@
 			bound_idxs = None
 		else:
 			break
-
-	return G, bound_idxs
+		
+		# Obtain decomposition matrices Rd
+		R = F.dot(G0)
+		print 'R, F, G', R.shape, F.shape, G.shape
+	return F, G0, R, bound_idxs
--- a/novelty.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/novelty.py	Wed Dec 09 16:27:10 2015 +0000
@@ -29,7 +29,8 @@
 peak_picker.params.Medfilt_on = True
 peak_picker.params.Polyfit_on = True
 peak_picker.params.isMedianPositive = False
-	
+peak_picker.params.gt = None
+
 def getNoveltyCurve(ssm, kernel_size, normalise=False):
 	'''Return novelty score from ssm.'''
 
--- a/sf.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/sf.py	Wed Dec 09 16:27:10 2015 +0000
@@ -29,128 +29,133 @@
 from utils import SegUtil
 
 def median_filter(X, M=8):
-    """Median filter along the first axis of the feature matrix X."""
-    for i in xrange(X.shape[1]):
-        X[:, i] = filters.median_filter(X[:, i], size=M)
-    return X
+	"""Median filter along the first axis of the feature matrix X."""
+	for i in xrange(X.shape[1]):
+		X[:, i] = filters.median_filter(X[:, i], size=M)
+	return X
 
 
 def gaussian_filter(X, M=8, axis=0):
-    """Gaussian filter along the first axis of the feature matrix X."""
-    for i in xrange(X.shape[axis]):
-        if axis == 1:
-            X[:, i] = filters.gaussian_filter(X[:, i], sigma=M / 2.)
-        elif axis == 0:
-            X[i, :] = filters.gaussian_filter(X[i, :], sigma=M / 2.)
-    return X
+	"""Gaussian filter along the first axis of the feature matrix X."""
+	for i in xrange(X.shape[axis]):
+		if axis == 1:
+			X[:, i] = filters.gaussian_filter(X[:, i], sigma=M / 2.)
+		elif axis == 0:
+			X[i, :] = filters.gaussian_filter(X[i, :], sigma=M / 2.)
+	return X
 
 
 def compute_gaussian_krnl(M):
-    """Creates a gaussian kernel following Serra's paper."""
-    g = signal.gaussian(M, M / 3., sym=True)
-    G = np.dot(g.reshape(-1, 1), g.reshape(1, -1))
-    G[M / 2:, :M / 2] = -G[M / 2:, :M / 2]
-    G[:M / 2, M / 1:] = -G[:M / 2, M / 1:]
-    return G
+	"""Creates a gaussian kernel following Serra's paper."""
+	g = signal.gaussian(M, M / 3., sym=True)
+	G = np.dot(g.reshape(-1, 1), g.reshape(1, -1))
+	G[M / 2:, :M / 2] = -G[M / 2:, :M / 2]
+	G[:M / 2, M / 1:] = -G[:M / 2, M / 1:]
+	return G
 
 
 def compute_nc(X):
-    """Computes the novelty curve from the structural features."""
-    N = X.shape[0]
-    # nc = np.sum(np.diff(X, axis=0), axis=1) # Difference between SF's
+	"""Computes the novelty curve from the structural features."""
+	N = X.shape[0]
+	# nc = np.sum(np.diff(X, axis=0), axis=1) # Difference between SF's
 
-    nc = np.zeros(N)
-    for i in xrange(N - 1):
-        nc[i] = distance.euclidean(X[i, :], X[i + 1, :])
+	nc = np.zeros(N)
+	for i in xrange(N - 1):
+		nc[i] = distance.euclidean(X[i, :], X[i + 1, :])
 
-    # Normalize
-    nc += np.abs(nc.min())
-    nc /= nc.max()
-    return nc
+	# Normalize
+	nc += np.abs(nc.min())
+	nc /= nc.max()
+	return nc
 
 
 def pick_peaks(nc, L=16, offset_denom=0.1):
-    """Obtain peaks from a novelty curve using an adaptive threshold."""
-    offset = nc.mean() * float(offset_denom)
-    th = filters.median_filter(nc, size=L) + offset
-    peaks = []
-    for i in xrange(1, nc.shape[0] - 1):
-        # is it a peak?
-        if nc[i - 1] < nc[i] and nc[i] > nc[i + 1]:
-            # is it above the threshold?
-            if nc[i] > th[i]:
-                peaks.append(i)
-    #plt.plot(nc)
-    #plt.plot(th)
-    #for peak in peaks:
-        #plt.axvline(peak, color="m")
-    #plt.show()
-    return peaks
+	"""Obtain peaks from a novelty curve using an adaptive threshold."""
+	offset = nc.mean() * float(offset_denom)
+	th = filters.median_filter(nc, size=L) + offset
+	peaks = []
+	for i in xrange(1, nc.shape[0] - 1):
+		# is it a peak?
+		if nc[i - 1] < nc[i] and nc[i] > nc[i + 1]:
+			# is it above the threshold?
+			if nc[i] > th[i]:
+				peaks.append(i)
+	#plt.plot(nc)
+	#plt.plot(th)
+	#for peak in peaks:
+		#plt.axvline(peak, color="m")
+	#plt.show()
+	return peaks
 
 
 def circular_shift(X):
-    """Shifts circularly the X squre matrix in order to get a
-        time-lag matrix."""
-    N = X.shape[0]
-    L = np.zeros(X.shape)
-    for i in xrange(N):
-        L[i, :] = np.asarray([X[(i + j) % N, j] for j in xrange(N)])
-    return L
+	"""Shifts circularly the X squre matrix in order to get a
+		time-lag matrix."""
+	N = X.shape[0]
+	L = np.zeros(X.shape)
+	for i in xrange(N):
+		L[i, :] = np.asarray([X[(i + j) % N, j] for j in xrange(N)])
+	return L
 
 
 def embedded_space(X, m, tau=1):
-    """Time-delay embedding with m dimensions and tau delays."""
-    N = X.shape[0] - int(np.ceil(m))
-    Y = np.zeros((N, int(np.ceil(X.shape[1] * m))))
-    for i in xrange(N):
-        rem = int((m % 1) * X.shape[1])  # Reminder for float m
-        Y[i, :] = np.concatenate((X[i:i + int(m), :].flatten(),
-                                 X[i + int(m), :rem]))
-    return Y
+	"""Time-delay embedding with m dimensions and tau delays."""
+	N = X.shape[0] - int(np.ceil(m))
+	Y = np.zeros((N, int(np.ceil(X.shape[1] * m))))
+	for i in xrange(N):
+		rem = int((m % 1) * X.shape[1])	 # Reminder for float m
+		Y[i, :] = np.concatenate((X[i:i + int(m), :].flatten(),
+								 X[i + int(m), :rem]))
+	return Y
 
 
-def segmentation(F):
-    """Main process."""
+def segmentation(F, return_ssm=False):
+	"""Main process."""
 
-    # Structural Features params
-    Mp = 32         # Size of the adaptive threshold for peak picking
-    od = 0.1        # Offset coefficient for adaptive thresholding
+	# Structural Features params
+	Mp = 32			# Size of the adaptive threshold for peak picking
+	od = 0.1		# Offset coefficient for adaptive thresholding
 
-    M = 16          # Size of gaussian kernel in beats
-    m = 3           # Number of embedded dimensions
-    k = 0.06        # k*N-nearest neighbors for the recurrence plot
+	M = 16			# Size of gaussian kernel in beats
+	m = 3			# Number of embedded dimensions
+	k = 0.06		# k*N-nearest neighbors for the recurrence plot
 
-    # Emedding the feature space (i.e. shingle)
-    E = embedded_space(F, m)
+	# Emedding the feature space (i.e. shingle)
+	E = embedded_space(F, m)
 
-    # Recurrence matrix
-    R = SegUtil.recurrence_matrix(E.T, k=k * int(F.shape[0]),
-                                width=0,  # zeros from the diagonal
-                                metric="seuclidean",
-                                sym=True).astype(np.float32)
+	# Recurrence matrix
+	R = SegUtil.recurrence_matrix(E.T, k=k * int(F.shape[0]),
+								width=0,  # zeros from the diagonal
+								metric="seuclidean",
+								sym=True).astype(np.float32)
 
-    # Check size in case the track is too short
-    if R.shape[0] > 0:
-        # Circular shift
-        L = circular_shift(R)
+	# Check size in case the track is too short
+	if R.shape[0] > 0:
+		# Circular shift
+		L = circular_shift(R)
 
-        # Obtain structural features by filtering the lag matrix
-        SF = gaussian_filter(L.T, M=M, axis=1)
-        SF = gaussian_filter(L.T, M=1, axis=0)
-        # plt.imshow(SF.T, interpolation="nearest", aspect="auto"); plt.show()
+		# Obtain structural features by filtering the lag matrix
+		SF = gaussian_filter(L.T, M=M, axis=1)
+		SF = gaussian_filter(L.T, M=1, axis=0)
+		# plt.imshow(SF.T, interpolation="nearest", aspect="auto"); plt.show()
 
-        # Compute the novelty curve
-        nc = compute_nc(SF)
+		# Compute the novelty curve
+		nc = compute_nc(SF)
+		if nc.max == 0:
+			return nc, np.asarray([]) 
+			
+		# Find peaks in the novelty curve
+		est_bounds = pick_peaks(nc, L=Mp, offset_denom=od)
 
-        # Find peaks in the novelty curve
-        est_bounds = pick_peaks(nc, L=Mp, offset_denom=od)
+		# Re-align embedded space
+		est_bound_idxs = np.asarray(est_bounds) + int(np.ceil(m / 2.))
+	else:
+		est_bound_idxs = []
 
-        # Re-align embedded space
-        est_bound_idxs = np.asarray(est_bounds) + int(np.ceil(m / 2.))
-    else:
-        est_bound_idxs = []
+	if len(est_bound_idxs) == 0:
+		est_bound_idxs = np.asarray([0])  # Return first one
+	
+	if return_ssm==True:
+		return E, R, SF, nc, est_bound_idxs
 
-    if len(est_bound_idxs) == 0:
-        est_bound_idxs = np.asarray([0])  # Return first one
-
-    return nc, est_bound_idxs
+	return nc, est_bound_idxs
--- a/utils/OnsetPlotProc.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/utils/OnsetPlotProc.py	Wed Dec 09 16:27:10 2015 +0000
@@ -6,14 +6,14 @@
 import cPickle as pickle
 
 # set this True or False to enable/disable plotting
-plot_on = False
-# plot_on = True
+# plot_on = False
+plot_on = True
 
 if plot_on :
 	import matplotlib.pyplot as plt
 
-	# gt = np.genfromtxt('../annotation/qupujicheng_annotation_30_2/3nuqijie0215-0517.csv', delimiter=',')[:,0]
-	gt = np.genfromtxt('../annotation/TheBeatles/seg_tut/03LucyInTheSkyWithDiamonds.lab',)[:,0]
+	gt = np.genfromtxt('/Users/mitian/Documents/hg/segmenter/annotation/qupujicheng_annotation_30_3/10hongniang01.csv', delimiter=',')[:,0]
+	# gt = np.genfromtxt('../annotation/TheBeatles/seg_tut/03LucyInTheSkyWithDiamonds.lab',)[:,0]
 
 class OnsetPlot(object):
 	'''This class allows creating a series of plots easily.'''
@@ -49,9 +49,8 @@
 		axes.plot(markers,np.array(signal)[markers],symbol,markersize=12)
 		
 	def add_markers(self,markers,symbol="g^",subplot=-1):
-		# self.gt = gt
 		self.marker_plots.append([markers,symbol,subplot])
-		print len(self.gt)
+		
 	def show_in_subprocess(self):
 		'''Marshal the object into a separate subprocess to fix OS/X issues with threading.'''
 		cmd = "python %s" %__file__
--- a/utils/PeakPickerUtil.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/utils/PeakPickerUtil.py	Wed Dec 09 16:27:10 2015 +0000
@@ -13,9 +13,9 @@
 		class Params(object):
 			'''Just create a small efficient object for storing the parameters.'''
 			__slots__ = ['alpha','delta','QuadThresh_a','QuadThresh_b','QuadThresh_c','aCoeffs','bCoeffs',\
-			'preWin','postWin','LP_on','Medfilt_on','Polyfit_on','isMedianPositive','rawSensitivity']
+			'preWin','postWin','LP_on','Medfilt_on','Polyfit_on','isMedianPositive','rawSensitivity', 'gt']
 		self.params = Params()
-
+		
 		
 	def process(self, onset_df, calcu_env=False, prune = False):
 		'''Smooth and peak pick the detection function.'''
@@ -119,14 +119,14 @@
 		and 3) adaptive thresholding using a moving median filter with separately configurable pre/post window sizes.
 		'''
 		
-		if plot_on : onset_plot.add_plot(onset_df, title="raw novelty curve")
+		if plot_on : onset_plot.add_plot(onset_df, title="Raw novelty curve")
 
 		out_df = self.removeDCNormalize(onset_df)
 
 		if self.params.LP_on :
 			# Now we get the exact same filtered function produced by the QM-Vamp plugin:
 			out_df = filtfilt(self.params.bCoeffs, self.params.aCoeffs, out_df)
-			onset_plot.add_plot(out_df, title = "lowpass filtered novelty curve")
+			onset_plot.add_plot(out_df, title = "Novelty curve after low-pass filtering")
 
 		if self.params.Medfilt_on :
 			out_df = self.movingMedianFilter(out_df)
@@ -189,7 +189,7 @@
 			i += 1
 			
 		# onset_plot.add_plot(scratch,title = "median filter output", subplot = 1)
-		onset_plot.add_plot(scratch,title = "novelty curve after adaptive thresholding")
+		onset_plot.add_plot(onset_df-scratch-delta,title = "Novelty curve after adaptive thresholding")
 
 		for i in xrange(length) :
 			value = onset_df[i] - scratch[i] - delta
@@ -197,7 +197,7 @@
 			if isMedianPositive and value < 0.0 :
 				output[i] = 0.0
 
-		if plot_on : onset_plot.add_plot(onset_df-output,title = "smoothed novelty curve and detected boundaries")
+		if plot_on : onset_plot.add_plot(onset_df-scratch-delta,title = "Smoothed novelty curve and detected boundaries")
 
 		return output.tolist()
 		
--- a/utils/RankClustering.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/utils/RankClustering.py	Wed Dec 09 16:27:10 2015 +0000
@@ -38,7 +38,7 @@
 				
 		# Brute force hack; we exclude nodes whose neighbourhood is larger than 80% of all frames
 		# Proper solution: use the delta assymmetric KL divergence to identify near singularities
-		if len(self.neighborhood) > 0.7 * len(self.sorted_distances) :
+		if len(self.neighborhood) > 0.8 * len(self.sorted_distances) :
 			self.neighborhood = []
 		
 	def getStatistics(self):
--- a/utils/xmeans.py	Fri Aug 21 10:15:29 2015 +0100
+++ b/utils/xmeans.py	Wed Dec 09 16:27:10 2015 +0000
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 """Class that implements X-means."""
 
+import sys, os
 import argparse
 import numpy as np
 import logging
@@ -10,218 +11,219 @@
 from scipy.spatial import distance
 
 
-class XMeans:
-    def __init__(self, X, init_K=2, plot=False):
-        self.X = X
-        self.init_K = init_K
-        self.plot = plot
+class XMeans(object):
+	def __init__(self, X, init_K=2, plot=False):
+		self.X = X
+		self.init_K = init_K
+		self.plot = plot
 
-    def estimate_K_xmeans(self, th=0.2, maxK = 10):
-        """Estimates K running X-means algorithm (Pelleg & Moore, 2000)."""
+	def estimate_K_xmeans(self, th=0.2, maxK = 10):
+		"""Estimates K running X-means algorithm (Pelleg & Moore, 2000)."""
 
-        # Run initial K-means
-        means, labels = self.run_kmeans(self.X, self.init_K)
+		# Run initial K-means
+		means, labels = self.run_kmeans(self.X, self.init_K)
 
-        # Run X-means algorithm
-        stop = False
-        curr_K = self.init_K
-        while not stop:
-            stop = True
-            final_means = []
-            for k in xrange(curr_K):
-                # Find the data that corresponds to the k-th cluster
-                D = self.get_clustered_data(self.X, labels, k)
-                if len(D) == 0 or D.shape[0] == 1:
-                    continue
+		# Run X-means algorithm
+		stop = False
+		curr_K = self.init_K
+		while not stop:
+			stop = True
+			final_means = []
+			for k in xrange(curr_K):
+				# Find the data that corresponds to the k-th cluster
+				D = self.get_clustered_data(self.X, labels, k)
+				if len(D) == 0 or D.shape[0] == 1:
+					continue
 
-                # Whiten and find whitened mean
-                stdD = np.std(D, axis=0)
-                #D = vq.whiten(D)
-                D /= stdD  # Same as line above
-                mean = D.mean(axis=0)
+				# Whiten and find whitened mean
+				stdD = np.std(D, axis=0)
+				#D = vq.whiten(D)
+				D /= stdD  # Same as line above
+				mean = D.mean(axis=0)
 
-                # Cluster this subspace by half (K=2)
-                half_means, half_labels = self.run_kmeans(D, K=2)
+				# Cluster this subspace by half (K=2)
+				half_means, half_labels = self.run_kmeans(D, K=2)
 
-                # Compute BICs
-                bic1 = self.compute_bic(D, [mean], K=1,
-                                        labels=np.zeros(D.shape[0]),
-                                        R=D.shape[0])
-                bic2 = self.compute_bic(D, half_means, K=2,
-                                        labels=half_labels, R=D.shape[0])
+				# Compute BICs
+				bic1 = self.compute_bic(D, [mean], K=1,
+										labels=np.zeros(D.shape[0]),
+										R=D.shape[0])
+				bic2 = self.compute_bic(D, half_means, K=2,
+										labels=half_labels, R=D.shape[0])
 
-                # Split or not
-                max_bic = np.max([np.abs(bic1), np.abs(bic2)])
-                norm_bic1 = bic1 / max_bic
-                norm_bic2 = bic2 / max_bic
-                diff_bic = np.abs(norm_bic1 - norm_bic2)
+				# Split or not
+				max_bic = np.max([np.abs(bic1), np.abs(bic2)])
+				norm_bic1 = bic1 / max_bic
+				norm_bic2 = bic2 / max_bic
+				diff_bic = np.abs(norm_bic1 - norm_bic2)
 
-                # Split!
-                print "diff_bic", diff_bic
-                if diff_bic > th:
-                    final_means.append(half_means[0] * stdD)
-                    final_means.append(half_means[1] * stdD)
-                    curr_K += 1
-                    stop = False
-                # Don't split
-                else:
-                    final_means.append(mean * stdD)
+				# Split!
+				print "diff_bic", diff_bic
+				if diff_bic > th:
+					final_means.append(half_means[0] * stdD)
+					final_means.append(half_means[1] * stdD)
+					curr_K += 1
+					stop = False
+				# Don't split
+				else:
+					final_means.append(mean * stdD)
 
-            final_means = np.asarray(final_means)
+			final_means = np.asarray(final_means)
 
-            print "Estimated K: ", curr_K
-            if self.plot:
-                plt.scatter(self.X[:, 0], self.X[:, 1])
-                plt.scatter(final_means[:, 0], final_means[:, 1], color="y")
-                plt.show()
+			print "Estimated K: ", curr_K
+			if self.plot:
+				plt.scatter(self.X[:, 0], self.X[:, 1])
+				plt.scatter(final_means[:, 0], final_means[:, 1], color="y")
+				plt.show()
 
-            if curr_K >= maxK or self.X.shape[-1] != final_means.shape[-1]:
-                stop = True
-            else:
-                labels, dist = vq.vq(self.X, final_means)
+			if curr_K >= maxK or self.X.shape[-1] != final_means.shape[-1]:
+				stop = True
+			else:
+				labels, dist = vq.vq(self.X, final_means)
 
-        return curr_K
+		return curr_K
 
-    def estimate_K_knee(self, th=.015, maxK=12):
-        """Estimates the K using K-means and BIC, by sweeping various K and
-            choosing the optimal BIC."""
-        # Sweep K-means
-        if self.X.shape[0] < maxK:
-            maxK = self.X.shape[0]
-        if maxK < 2:
-            maxK = 2
-        K = np.arange(1, maxK)
-        bics = []
-        for k in K:
-            means, labels = self.run_kmeans(self.X, k)
-            bic = self.compute_bic(self.X, means, labels, K=k,
-                                   R=self.X.shape[0])
-            bics.append(bic)
-        diff_bics = np.diff(bics)
-        finalK = K[-1]
+	def estimate_K_knee(self, th=.015, maxK=12):
+		"""Estimates the K using K-means and BIC, by sweeping various K and
+			choosing the optimal BIC."""
+		# Sweep K-means
+		if self.X.shape[0] < maxK:
+			maxK = self.X.shape[0]
+		if maxK < 2:
+			maxK = 2
+		K = np.arange(1, maxK)
+		bics = []
+		for k in K:
+			means, labels = self.run_kmeans(self.X, k)
+			print 'means, labels', means.shape, len(labels)
+			bic = self.compute_bic(self.X, means, labels, K=k,
+								   R=self.X.shape[0])
+			bics.append(bic)
+		diff_bics = np.diff(bics)
+		finalK = K[-1]
 
-        if len(bics) == 1:
-            finalK = 2
-        else:
-            # Normalize
-            bics = np.asarray(bics)
-            bics -= bics.min()
-            #bics /= bics.max()
-            diff_bics -= diff_bics.min()
-            #diff_bics /= diff_bics.max()
+		if len(bics) == 1:
+			finalK = 2
+		else:
+			# Normalize
+			bics = np.asarray(bics)
+			bics -= bics.min()
+			#bics /= bics.max()
+			diff_bics -= diff_bics.min()
+			#diff_bics /= diff_bics.max()
 
-            #print bics, diff_bics
+			#print bics, diff_bics
 
-            # Find optimum K
-            for i in xrange(len(K[:-1])):
-                #if bics[i] > diff_bics[i]:
-                if diff_bics[i] < th and K[i] != 1:
-                    finalK = K[i]
-                    break
+			# Find optimum K
+			for i in xrange(len(K[:-1])):
+				#if bics[i] > diff_bics[i]:
+				if diff_bics[i] < th and K[i] != 1:
+					finalK = K[i]
+					break
 
-        logging.info("Estimated Unique Number of Segments: %d" % finalK)
-        if self.plot:
-            plt.subplot(2, 1, 1)
-            plt.plot(K, bics, label="BIC")
-            plt.plot(K[:-1], diff_bics, label="BIC diff")
-            plt.legend(loc=2)
-            plt.subplot(2, 1, 2)
-            plt.scatter(self.X[:, 0], self.X[:, 1])
-            plt.show()
+		logging.info("Estimated Unique Number of Segments: %d" % finalK)
+		if self.plot:
+			plt.subplot(2, 1, 1)
+			plt.plot(K, bics, label="BIC")
+			plt.plot(K[:-1], diff_bics, label="BIC diff")
+			plt.legend(loc=2)
+			plt.subplot(2, 1, 2)
+			plt.scatter(self.X[:, 0], self.X[:, 1])
+			plt.show()
 
-        return finalK
+		return finalK
 
-    def get_clustered_data(self, X, labels, label_index):
-        """Returns the data with a specific label_index, using the previously
-         learned labels."""
-        D = X[np.argwhere(labels == label_index)]
-        return D.reshape((D.shape[0], D.shape[-1]))
+	def get_clustered_data(self, X, labels, label_index):
+		"""Returns the data with a specific label_index, using the previously
+		 learned labels."""
+		D = X[np.argwhere(labels == label_index)]
+		return D.reshape((D.shape[0], D.shape[-1]))
 
-    def run_kmeans(self, X, K):
-        """Runs k-means and returns the labels assigned to the data."""
-        wX = vq.whiten(X)
-        means, dist = vq.kmeans(wX, K, iter=100)
-        labels, dist = vq.vq(wX, means)
-        return means, labels
+	def run_kmeans(self, X, K):
+		"""Runs k-means and returns the labels assigned to the data."""
+		wX = vq.whiten(X)
+		means, dist = vq.kmeans(wX, K, iter=100)
+		labels, dist = vq.vq(wX, means)
+		return means, labels
 
-    def compute_bic(self, D, means, labels, K, R):
-        """Computes the Bayesian Information Criterion."""
-        D = vq.whiten(D)
-        Rn = D.shape[0]
-        M = D.shape[1]
+	def compute_bic(self, D, means, labels, K, R):
+		"""Computes the Bayesian Information Criterion."""
+		D = vq.whiten(D)
+		Rn = D.shape[0]
+		M = D.shape[1]
 
-        if R == K:
-            return 1
+		if R == K:
+			return 1
 
-        # Maximum likelihood estimate (MLE)
-        mle_var = 0
-        for k in xrange(len(means)):
-            X = D[np.argwhere(labels == k)]
-            X = X.reshape((X.shape[0], X.shape[-1]))
-            for x in X:
-                mle_var += distance.euclidean(x, means[k])
-                #print x, means[k], mle_var
-        mle_var /= (float(R - K))
+		# Maximum likelihood estimate (MLE)
+		mle_var = 0
+		for k in xrange(len(means)):
+			X = D[np.argwhere(labels == k)]
+			X = X.reshape((X.shape[0], X.shape[-1]))
+			for x in X:
+				mle_var += distance.euclidean(x, means[k])
+				#print x, means[k], mle_var
+		mle_var /= (float(R - K))
 
-        # Log-likelihood of the data
-        l_D = - Rn/2. * np.log(2*np.pi) - (Rn * M)/2. * np.log(mle_var) - \
-            (Rn - K) / 2. + Rn * np.log(Rn) - Rn * np.log(R)
+		# Log-likelihood of the data
+		l_D = - Rn/2. * np.log(2*np.pi) - (Rn * M)/2. * np.log(mle_var) - \
+			(Rn - K) / 2. + Rn * np.log(Rn) - Rn * np.log(R)
 
-        # Params of BIC
-        p = (K-1) + M * K + mle_var
+		# Params of BIC
+		p = (K-1) + M * K + mle_var
 
-        #print "BIC:", l_D, p, R, K
+		#print "BIC:", l_D, p, R, K
 
-        # Return the bic
-        return l_D - p/2. * np.log(R)
+		# Return the bic
+		return l_D - p/2. * np.log(R)
 
-    @classmethod
-    def generate_2d_data(self, N=100, K=5):
-        """Generates N*K 2D data points with K means and N data points
-            for each mean."""
-        # Seed the random
-        np.random.seed(seed=int(time.time()))
+	@classmethod
+	def generate_2d_data(self, N=100, K=5):
+		"""Generates N*K 2D data points with K means and N data points
+			for each mean."""
+		# Seed the random
+		np.random.seed(seed=int(time.time()))
 
-        # Amount of spread of the centroids
-        spread = 30
+		# Amount of spread of the centroids
+		spread = 30
 
-        # Generate random data
-        X = np.empty((0, 2))
-        for i in xrange(K):
-            mean = np.array([np.random.random()*spread,
-                             np.random.random()*spread])
-            x = np.random.normal(0.0, scale=1.0, size=(N, 2)) + mean
-            X = np.append(X, x, axis=0)
+		# Generate random data
+		X = np.empty((0, 2))
+		for i in xrange(K):
+			mean = np.array([np.random.random()*spread,
+							 np.random.random()*spread])
+			x = np.random.normal(0.0, scale=1.0, size=(N, 2)) + mean
+			X = np.append(X, x, axis=0)
 
-        return X
+		return X
 
 
 def test_kmeans(K=5):
-    """Test k-means with the synthetic data."""
-    X = XMeans.generate_2d_data(K=4)
-    wX = vq.whiten(X)
-    dic, dist = vq.kmeans(wX, K, iter=100)
+	"""Test k-means with the synthetic data."""
+	X = XMeans.generate_2d_data(K=4)
+	wX = vq.whiten(X)
+	dic, dist = vq.kmeans(wX, K, iter=100)
 
-    plt.scatter(wX[:, 0], wX[:, 1])
-    plt.scatter(dic[:, 0], dic[:, 1], color="m")
-    plt.show()
+	plt.scatter(wX[:, 0], wX[:, 1])
+	plt.scatter(dic[:, 0], dic[:, 1], color="m")
+	plt.show()
 
 
 def main(args):
-    #test_kmeans(6)
-    X = XMeans.generate_2d_data(K=args.k)
-    xmeans = XMeans(X, init_K=2, plot=args.plot)
-    est_K = xmeans.estimate_K_xmeans()
-    est_K_knee = xmeans.estimate_K_knee()
-    print "Estimated x-means K:", est_K
-    print "Estimated Knee Point Detection K:", est_K_knee
+	#test_kmeans(6)
+	X = XMeans.generate_2d_data(K=args.k)
+	xmeans = XMeans(X, init_K=2, plot=args.plot)
+	est_K = xmeans.estimate_K_xmeans()
+	est_K_knee = xmeans.estimate_K_knee()
+	print "Estimated x-means K:", est_K
+	print "Estimated Knee Point Detection K:", est_K_knee
 
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(
-        description="Runs x-means")
-    parser.add_argument("k",
-                        metavar="k", type=int,
-                        help="Number of clusters to estimate.")
-    parser.add_argument("-p", action="store_true", default=False,
-                        dest="plot", help="Plot the results")
-    main(parser.parse_args())
+	parser = argparse.ArgumentParser(
+		description="Runs x-means")
+	parser.add_argument("k",
+						metavar="k", type=int,
+						help="Number of clusters to estimate.")
+	parser.add_argument("-p", action="store_true", default=False,
+						dest="plot", help="Plot the results")
+	main(parser.parse_args())