def Train_Database_Sign(self, 
                 database,
                 version,
                 num_of_kpts,
                 force_update = False,                          
                 K = 10,#tree branch
                 depth = 4, #depth
                 nleaves = 10000 #leaves in the tree
                 ):
                    
        #load information from database
        num_in_set = database[0]
        num_of_sets = database[1]
        data_dir = database[2]   
        total = num_in_set * num_of_sets

        updated = force_update # will be turned true if one of the steps has been processed, so that the following step will be focused to processs!
        

        
        
        '''
        generate desc~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dir should be saved
        '''
        
        desc_dir = os.path.join(self.DESC_DIR, 'db_version_'+str(version), str(num_of_kpts))
        if updated or (not os.path.isdir(desc_dir) or os.listdir(desc_dir) == []):
            updated = True
            
            if not os.path.isdir(os.path.join(self.DESC_DIR, 'db_version_'+str(version))):
                os.mkdir(os.path.join(self.DESC_DIR, 'db_version_'+str(version)))
            if not os.path.isdir(desc_dir):
                os.mkdir(desc_dir)
            
            for d in data_dir:  
                img_idx = d[0]         
                class_idx = d[1]
                img_dir = d[2]
                
                '''
                k is the index of desc included in the name, should be ordered by the class 
                '''
                k = img_idx + class_idx * num_in_set
                
                #load image(load image, convert to np array with float type)
                img = Image.open(img_dir).convert('L')
                img_s = self.StandalizeImage(img, 480)
                
                img_data = np.asarray(img_s, dtype=float)
        
                kp = Keypoint()   
                kp.generate_keypoint(num_of_kpts, img.size[0], img.size[1], self.SIGMA)   #sigma is set to 1 currently
                #kp.save_keypoint(self.KEYPOINT_DIR, self.KEYPOINT_FILE+str(num_of_kpts)) #save to a directory

                print 'Random keypoint generated'
        
                #generate desc
                desc = Descriptor()
                desc.generate_desc(img_data, kp.kpt)
                desc.save_desc(desc_dir, self.DESC_FILE + str(k))
    
                print desc.desc
                
                #load to a large matrix
                #desc_database[:, k*num_of_kpts:k+num_of_kpts] = desc.desc #add to the database therefore later can be used to train the tree
                print '=>'+str(k) ,
                
            print 'Descriptor Generated'
            
                        
        #load desc 
        desc_database = np.empty(shape=(128, total*num_of_kpts), dtype=np.uint8)
        for k in range(0, total):
            desc = Descriptor()
            desc.load_desc(desc_dir, self.DESC_FILE + str(k))
            desc_database[:, k*num_of_kpts:(k+1)*num_of_kpts] = desc.desc
            
        print 'Descriptor Loaded'
        
        '''
        Build the tree~~~~~~~~~~~~~~~~~~~~~~~~~
        '''
        tree_dir = os.path.join(self.TREE_DIR, 'db_version_' + str(version))
        if updated or (not os.path.isfile(os.path.join(tree_dir, str(num_of_kpts) + self.TREE_FILE))): 
            updated = True
            if not os.path.isdir(tree_dir):
                os.mkdir(tree_dir)
                      
            tree = Tree()
            tree.generate_tree(desc_database, K, nleaves, tree_dir, str(num_of_kpts) + self.TREE_FILE)
        
            print 'Tree built'
   

        '''
        Generate signature~~~~~~~~~~~~~~~~~~~~~~~~~
        '''      
            
        sign_dir = os.path.join(self.SIGN_DIR, 'db_version_' + str(version))
        
        if updated or (not os.path.isfile(os.path.join(sign_dir, self.SIGN_FILE+str(num_of_kpts)))):
            updated = True
            
            tr = vl._vlfeat.VlHIKMTree(0, 0)
            tr.load(os.path.join(tree_dir, str(num_of_kpts) + self.TREE_FILE))
            
            print 'Tree Loaded'
            
            sign = Signature()
            sign.generate_sign_database_dir(tr, desc_database, K, depth, total, num_of_kpts)
    
            if not os.path.isdir(sign_dir):
                os.mkdir(sign_dir)
                
            sign.save_sign(sign_dir, self.SIGN_FILE+str(num_of_kpts))
            
            print 'Signature Generated'
        
        else:
            print 'Signature Already Generated'
        
        del desc_database
        
        return updated;
	# x = np.linspace(0, 1, 200)
	# y = x ** 2

	x = np.linspace(0, 2 * np.pi, 100)
	y = np.sin(x)
	noise = np.random.rand(y.shape[0]) * 0.4
	y = y + noise

	data = np.array([x, y]).T

	fig_data = plt.figure(figsize=(20, 10))
	plt.scatter(data[:, 0], data[:, 1])
	plt.show()

	tree = Tree(data, max_depth=7)
	tree.generate_tree(error=5.0e-2)

	x_max = x.max()
	x_min = x.min()
	y_max = y.max()
	y_min = y.min()

	x_v = np.linspace(x_min, x_max, 500)
	y_v = np.linspace(y_min, y_max, 100)
	x_im, y_im = np.meshgrid(x_v, y_v)
	z = np.zeros(x_im.shape)

	count = x_im.shape[0] * x_im.shape[1]
	pos = 0
	for i in np.arange(0, x_im.shape[0], 1):
		for j in np.arange(0, x_im.shape[1], 1):