# stuff in this file
#
# Main BDTrajectory object. 
# class BDTrajectory( BDObject )
#	def __init__( self, x, order, verbose )
#   def __len__( self )
#   def __str__( self )
#   def _get_x( self )
#   def _set_x( self, x )
#   def _get_order( self ): return self._order
#   def _set_order( self, value ) 
#   def _compute_delta_x( self )
#   def _get_x0( self )
#   def _get_sxdx( self ) 
#
# Function to load a trajectory from file and generate a BDTrajectory of given order.
# def load_trajectory( filename, order ) 
#
# Function to load a trajectory from SQL of the given order, using the given query.
# Currently nonfunctional.
# def trajectory_from_sql( query, database, host, user, password, order ) 
#
# Exception for when an odd order is requested. 
# class OddOrder( Exception ) 
#   def __init__( self, value )
#   def __str__( self )
#
# Exception for when the 'x' property of BDTrajectory is modified beyond the first time.
# class ModifyUnmodifiableConstant( Exception )
#   def __str__( self )

from BDObject import BDObject
from numpy import array, loadtxt
import MySQLdb

# object needs 1-d trajectory data from a list or numpy array
class BDTrajectory( BDObject ):
	
	def __init__( self, x, x0, order, verbose = False):
		BDObject.__init__( self, verbose )
		self._x_is_set = False
		self.x0 = x0
		self.x = x # property pointing to self._x
		
	def __len__( self ):
		return self._length

	def __str__( self ):
		return list.__str__( self.x )
 
	def _get_x( self ):
		return self._x
	def _set_x( self, x ):
		if not self._x_is_set :
			self._x_is_set = True
			self._x = array(x, "float" )
			self._compute_delta_x()
			self._length = len( self.x )
		else :
			raise ModifyUnmodifiableConstant
	x = property( _get_x, _set_x )

	def _compute_delta_x( self ) :
		deltax = [ self.x[0] - self.x0 ] # first point depends on known starting point
		for i in range( 1, len( self.x ) ) :
			deltax.append( self.x[i] - self.x[i-1] )
		self.deltax = array( deltax )

# Exceptions
class OddOrder( Exception ) :
	def __init__( self, value ): self.value = value
	def __str__( self ):
		return "Order must be even (got odd %d)" % self.value

class ModifyUnmodifiableConstant( Exception ):
	def __str__( self ):
		return "Can't modify object"

# Utility functions
def load_trajectory( filename, x0, order, scaling = 1.0, verbose = False ) :
	traj = loadtxt( filename, "float" )*scaling
	return BDTrajectory( traj, x0, order, verbose )

def trajectory_from_sql( query, database, host, user, password, order ) :
	print "trajectory_from_sql() not yet implemented. Returning None."
	return None
