x = to_array([0,1,2,3,4,5,6,7,8,9,10],'i')
y = to_array([1,2,3,4,5,10, 50, 11, 4,3,1],'i')




def to_array(obj, type = 'o'):   
    """Convert Python list to Java array.

    Args:
        obj(list): Original data.
        type(str): array type 'b' = byte, 'h' = short, 'i' = int, 'l' = long,  'f' = float, 'd' = double, 
                              'c' = char, 'z' = boolean, 's' = String,  'o' = Object 
    Returns:
        Java array.

    """     
    if type[0] == '[':
        type = type[1:]    
    arrayType = class_types.get("["+type)    

    if obj is None:
        return None
    if isinstance(obj,java.util.List):
        obj = obj.toArray(java.lang.reflect.Array.newInstance(Class.forName(class_types.get(type)),0))    
        if type != 'o':
            obj = Convert.toPrimitiveArray(obj)
    if isinstance(obj,PyArray):                
        if obj.typecode != type:
            print "DIF", obj.typecode, type
            ret = java.lang.reflect.Array.newInstance(Class.forName(class_types.get(type)),len(obj))            
            if type == 's':                              
                for i in range(len(obj)): ret[i] = str(obj[i])   
            elif type == 'c':                              
                for i in range(len(obj)): ret[i] = chr(obj[i])   
            else:      
                for i in range(len(obj)): ret[i] = obj[i]
            obj = ret
        if type not in ['o', 's']:
            obj = Convert.toPrimitiveArray(obj)
        return obj        
    if is_list(obj):
        if type=='o' or  type== 's':
            ret = java.lang.reflect.Array.newInstance(Class.forName(class_types.get(type)),len(obj))
            for i in range (len(obj)):
                if is_list(obj):
                    ret[i] = to_array(obj[i],type)
                elif type == 's':
                    ret[i] = str(obj[i])
                else:
                    ret[i] = obj[i]        
            return ret            

        if len(obj)>0 and is_list(obj[0]):
            if  len(obj[0])>0 and is_list(obj[0][0]):
                    ret = java.lang.reflect.Array.newInstance(Class.forName(arrayType),len(obj),len(obj[0]))                    
                    for i in range(len(obj)):
                        ret[i]=to_array(obj[i], type)            
                    return ret
            else:
                ret = java.lang.reflect.Array.newInstance(Class.forName(arrayType),len(obj))
                for i in range(len(obj)):
                    ret[i]=to_array(obj[i], type)            
                return ret     
        return jarray.array(obj,type)
    return obj


def plot(data, name = None, xdata = None, ydata=None, title=None):    
    """Request one or multiple plots of user data (1d, 2d or 3d)

    Args:
        data: array or list of values. For multiple plots, array of arrays or lists of values.
        name(str or list of str, optional): plot name or list of names (if multiple plots). 
        xdata: array or list of values. For multiple plots, array of arrays or lists of values.
        ydata: array or list of values. For multiple plots, array of arrays or lists of values.
        title(str, optional): plotting context name.

    Returns:
        ArrayList of Plot objects.

    """      
    if isinstance(data, ch.psi.pshell.data.Table):       
        if is_list(xdata):            
            xdata = to_array(xdata, 'd')
        return get_context().plot(data,xdata,name,title)    
    if isinstance(data, ch.psi.pshell.scan.ScanResult):
        return get_context().plot(data,title)

    
    if (name is not None) and is_list(name):        
        if len(name)==0:
            name=None;
        else:
            if (data==None):                
                data = []
                for n in name:
                    data.append([])        
        plots = java.lang.reflect.Array.newInstance(Class.forName("ch.psi.pshell.data.PlotDescriptor"), len(data))                    
        for i in range (len(data)):         
            plotName = None if (name is None) else name[i]
            x = xdata 
            if is_list(x) and len(x)>0 and (is_list(x[i]) or isinstance(x[i] , java.util.List) or isinstance(x[i],PyArray)):
                x = x[i]                
            y = ydata
            if is_list(y) and len(y)>0 and (is_list(y[i]) or isinstance(y[i] , java.util.List) or isinstance(y[i],PyArray)):
                y = y[i]
            plots[i] =  PlotDescriptor(plotName , to_array(data[i], 'd'), to_array(x, 'd'), to_array(y, 'd'))                    
        return get_context().plot(plots,title)
    else:        
        plot = PlotDescriptor(name, to_array(data, 'd'), to_array(xdata, 'd'), to_array(ydata, 'd'))
        return get_context().plot(plot,title)




from mathutils import estimate_peak_indexes, fit_gaussians, create_fit_point_list, Gaussian,fit_harmonic,HarmonicOscillator
import java.awt.Color as Color

def fit(ydata, xdata = None):
    if xdata is None:
        xdata = frange(0, len(ydata), 1)
    max_y= max(ydata)    
    index_max = ydata.index(max_y)    
    max_x= xdata[index_max]
    print "Max index:" + str(index_max),
    print " x:" + str(max_x),
    print " y:" + str(max_y)
    
    gaussians = fit_gaussians(ydata, xdata, [index_max,])

    print "PLOT"

    ydata =to_array(ydata,'d')
    xdata= to_array(xdata,'d')
      
    p = plot([ydata],["data"],[xdata], title="Fit" )[0] 
    print "OK"

    if gaussians[0] is None:  #Fitting error
        p.addMarker(max_x, None, "Max="+str(round(max_x,2)), Color.GRAY)
        print "Fitting error - using max value"
        return (None, max_x, None)
    
    (norm, mean, sigma) = gaussians[0]

    fitted_gaussian_function = Gaussian(norm, mean, sigma)    
    scale_x = [float(min(xdata)), float(max(xdata)) ]
    points = max((len(xdata)+1), 100)
    resolution = (scale_x[1]-scale_x[0]) / points    
    fit_y = []
    fit_x = frange(scale_x[0],scale_x[1],resolution, True)
    for x in fit_x:
        fit_y.append(fitted_gaussian_function.value(x))    
    p.addSeries(LinePlotSeries("fit"))
    p.getSeries(1).setData(fit_x, fit_y)    
    
    if abs(mean - xdata[index_max]) < ((scale_x[0] + scale_x[1])/2):
        print "Mean -> " +  str(mean)
        p.addMarker(mean, None, "Mean="+str(round(norm,2)), Color.MAGENTA.darker())
        return (norm, mean, sigma)
    else:
        p.addMarker(max_x, None, "Max="+str(round(max_x,2)), Color.GRAY)
        print "Invalid gaussian fit: " +  str(mean) + " - using max value"
        return (None, max_x, None)

fit(y,x)