def fitDataRigidScaleNoCorr_TwoSurfaces( X1,X2,data1,data2, xtol=1e-5, maxfev=0, t0=None ):
	""" fit list of points X to list of points data by minimising
	least squares distance between each point in X and closest neighbour
	in data
	"""
	if t0==None:
		t0 = scipy.array([0.0,0.0,0.0,0.0,0.0,0.0,1.0])
			
	data1Tree = cKDTree( data1 )
	data2Tree = cKDTree( data2 )
	X1 = scipy.array(X1)
	X2 = scipy.array(X2)
	
	def obj( t ):
		x1R = transformRigid3D( X1, t[:6] )
		x1RS = transformScale3D( x1R, scipy.ones(3)*t[6] )
		d1 = data1Tree.query( list(x1RS) )[0]
		x2R = transformRigid3D( X2, t[:6] )
		x2RS = transformScale3D( x2R, scipy.ones(3)*t[6] )
		d2 = data2Tree.query( list(x2RS) )[0]
		d=concatenate((d1,d2),0)
		return d*d
		
	tOpt = leastsq( obj, t0, xtol=xtol, maxfev=maxfev )[0]
	X1Opt = transformRigid3D( X1, tOpt[:6] )
	X2Opt = transformRigid3D( X2, tOpt[:6] )
	X1Opt = transformScale3D( X1Opt, tOpt[6:] )
	X2Opt = transformScale3D( X2Opt, tOpt[6:] )
	
	return tOpt, X1Opt,X2Opt
	def obj( t ):
		x1R = transformRigid3D( X1, t[:6] )
		x1RS = transformScale3D( x1R, scipy.ones(3)*t[6] )
		d1 = data1Tree.query( list(x1RS) )[0]
		x2R = transformRigid3D( X2, t[:6] )
		x2RS = transformScale3D( x2R, scipy.ones(3)*t[6] )
		d2 = data2Tree.query( list(x2RS) )[0]
		d=concatenate((d1,d2),0)
		return d*d
	def obj( t ):
		x1R = transformRigid3D( X1, t[:6] )
		x1SR = transformScale3D( x1R, t[6:] )
		x1SRTree = cKDTree(x1SR)
		d1 = x1SRTree.query( list(data1) )[0]
		x2R = transformRigid3D( X2, t[:6] )
		x2SR = transformScale3D( x2R, t[6:] )
		x2SRTree = cKDTree(x2SR)
		d2 = x2SRTree.query( list(data2) )[0]
		d=concatenate((d1,d2),0)
		return d*d
	def obj( t ):
		x1S = transformScale3D( X1, t[6:] )
		x1RS = transformRigid3D( x1S, t[:6] )
		x1RSTree = cKDTree(x1RS)
		d1 = x1RSTree.query( list(data1) )[0]
		x2S = transformScale3D( X2, t[6:] )
		x2RS = transformRigid3D( x2S, t[:6] )
		x2RSTree = cKDTree(x2RS)
		d2 = x2RSTree.query( list(data2) )[0]
		d=concatenate((d1,d2),0)
		#print t
		SSQ.append(scipy.sum(d*d))
		return d*d
def fitDataAnisotropicScaleRigidNoCorr_ModelTree_TwoSurfaces(X1, X2, data1, data2, filename, xtol=1e-5, maxfev=0,
                                                             t0=None):
    """ fit list of points X to list of points data by minimising
    least squares distance between each point in X and closest neighbour
    in data
    """
    if t0 == None:
        t0 = scipy.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0])

    data1 = scipy.array(data1)
    data2 = scipy.array(data2)
    SSQ = []

    def obj(t):
        x1S = transformScale3D(X1, t[6:])
        x1RS = transformRigid3D(x1S, t[:6])
        x1RSTree = cKDTree(x1RS)
        d1 = x1RSTree.query(list(data1))[0]
        x2S = transformScale3D(X2, t[6:])
        x2RS = transformRigid3D(x2S, t[:6])
        x2RSTree = cKDTree(x2RS)
        d2 = x2RSTree.query(list(data2))[0]
        d = concatenate((d1, d2), 0)
        #print t
        SSQ.append(scipy.sum(d * d))
        return d * d


    [tOpt, err] = leastsq(obj, t0, xtol=xtol, maxfev=maxfev)

    X1Opt = transformScale3D(X1, tOpt[6:])
    X2Opt = transformScale3D(X2, tOpt[6:])
    X1Opt = transformRigid3DFinal(X1Opt, tOpt[:6])
    X2Opt = transformRigid3DFinal(X2Opt, tOpt[:6])
    #t_translate_scale = []
    #t_translate_scale[0:3] = tOpt[0:3]
    #t_translate_scale[3:5] = tOpt[6:]
    #print t_translate_scale
    print tOpt
    writeTransformation_Scaling_Translation(tOpt, filename)
    #writeTransformation_Scaling_Translation(t_translate_scale, filename)
    #writeTransformation_Scaling(tOpt[6:],filename)
    #print tOpt
    #print 'Initial SSQ'
    #print SSQ[0]
    print 'Final SSQ'
    Final_SSQ = scipy.sum(obj(tOpt))
    #print SSQ
    print Final_SSQ

    return tOpt, X1Opt, X2Opt
def fitDataRigidAnisotropicScaleNoCorr_ModelTree_TwoSurfaces( X1,X2, data1,data2, filename,xtol=1e-5, maxfev=0, t0=None):
	""" fit list of points X to list of points data by minimising
	least squares distance between each point in X and closest neighbour
	in data
	"""
	if t0==None:
		t0 = scipy.array([0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0])
			
	data1 = scipy.array(data1)
	data2 = scipy.array(data2)
	
	def obj( t ):
		x1R = transformRigid3D( X1, t[:6] )
		x1SR = transformScale3D( x1R, t[6:] )
		x1SRTree = cKDTree(x1SR)
		d1 = x1SRTree.query( list(data1) )[0]
		x2R = transformRigid3D( X2, t[:6] )
		x2SR = transformScale3D( x2R, t[6:] )
		x2SRTree = cKDTree(x2SR)
		d2 = x2SRTree.query( list(data2) )[0]
		d=concatenate((d1,d2),0)
		return d*d
		
		
	tOpt = leastsq( obj, t0, xtol=xtol, maxfev=maxfev )[0]
	X1Opt = transformRigid3DFinal( X1, tOpt[:6] )
	X2Opt = transformRigid3DFinal( X2, tOpt[:6] )
	X1Opt = transformScale3D( X1Opt, tOpt[6:] )	
	X2Opt = transformScale3D( X2Opt, tOpt[6:] )
	
	writeTransformation_Scaling(tOpt[6:],filename)
	
	print 'Final SSQ'
	Final_SSQ=scipy.sum(obj(tOpt))
	print Final_SSQ

 
	return tOpt, X1Opt,X2Opt
def fitDataRigidAnisotropicScaleNoCorr_ModelTree( X, data, xtol=1e-5, maxfev=0, t0=None ):
	""" fit list of points X to list of points data by minimising
	least squares distance between each point in X and closest neighbour
	in data
	"""
	if t0==None:
		t0 = scipy.array([0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0])
			
	data = scipy.array(data)
	
	def obj( t ):
		xR = transformRigid3D( X, t[:6] )
		xRS = transformScale3D( xR, t[6:] )
		xRSTree = cKDTree(xRS)
		d = xRSTree.query( list(data) )[0]
		return d*d
		
	tOpt = leastsq( obj, t0, xtol=xtol, maxfev=maxfev )[0]
	XOpt = transformRigid3DFinal( X, tOpt[:6] )
	XOpt = transformScale3D( XOpt, tOpt[6:] )
	
	return tOpt, XOpt
def fitDataRigidScaleNoCorr( X, data, xtol=1e-5, maxfev=0, t0=None ):
	""" fit list of points X to list of points data by minimising
	least squares distance between each point in X and closest neighbour
	in data
	"""
	if t0==None:
		t0 = scipy.array([0.0,0.0,0.0,0.0,0.0,0.0,1.0])
			
	dataTree = cKDTree( data )
	X = scipy.array(X)
	
	def obj( t ):
		xR = transformRigid3D( X, t[:6] )
		xRS = transformScale3D( xR, scipy.ones(3)*t[6] )
		d = dataTree.query( list(xRS) )[0]
		#~ print d.mean()
		return d*d
		
	tOpt = leastsq( obj, t0, xtol=xtol, maxfev=maxfev )[0]
	XOpt = transformRigid3D( X, tOpt[:6] )
	XOpt = transformScale3D( XOpt, tOpt[6:] )
	
	return tOpt, XOpt
	def obj( t ):
		xR = transformRigid3D( X, t[:6] )
		xRS = transformScale3D( xR, t[6:] )
		xRSTree = cKDTree(xRS)
		d = xRSTree.query( list(data) )[0]
		return d*d
	def obj( t ):
		xR = transformRigid3D( X, t[:6] )
		xRS = transformScale3D( xR, t[6:])
		d = dataTree.query( list(xRS) )[0]
		#~ print d.mean()
		return d*d