def Circulation_optimum(name):

    Data=np.load(name+'_vort.npy')
    Data=Data[1:-1,1:-1]
    re,P1,P2,P5,P7,P8=Circulation_Percentiles(Data)
    Suma=Data.sum()
    Data=np.load(name+'_omeg.npy')
    Data=Data[1:-1,1:-1]
    qe,Q1,Q2,Q5,Q7,Q8=Circulation_Percentiles(Data)

    k=200.0

    kd=0.1

    while k<1000:
        kd=kd*0.99
        kd=np.round(kd,1)
        VORT=difussion_image(name,k)
        VORT*=Data.sum()/VORT.sum()
        ERROR=1e10
        while kd<100:

            VORT2=difussion(VORT,kd,mode='wrap')

            res,P16,P25,P50,P75,P84=Circulation_Percentiles(VORT2)

            err1=((P8-P1)/P5)-((P84-P16)/P50)
            err2=((P7-P2)/P5)-((P75-P25)/P50)

            err1=np.sqrt(np.mean(err1[res<100]**2))
            err2=np.sqrt(np.mean(err2[res<100]**2))
            err=np.sqrt(err1**2+err2**2)*100
            print(err)
            if err<ERROR:
                ERROR=err
            elif err<1000 :
                plt.plot(re,(P8-P1)/P5,color="#38c3ff",linestyle='-')
                plt.plot(re,(P7-P2)/P5,color="#ffdb38",linestyle='-')

                plt.plot(qe,(Q8-Q1)/Q5,color="#38c3ff",linestyle='--')
                plt.plot(qe,(Q7-Q2)/Q5,color="#ffdb38",linestyle='--')

                VORT2=difussion(VORT,kd-0.1,mode='wrap')

                res,P16,P25,P50,P75,P84=Circulation_Percentiles(VORT2)
                plt.plot(res,(P84-P16)/P50,color="#38c3ff",linestyle=':')
                plt.plot(res,(P75-P25)/P50,color="#ffdb38",linestyle=':')
                plt.ylim(0,5)
                plt.xscale('log')
                plt.title('error_%08.4f' %err)
                plt.savefig('Temp_Files/Figures/kt_%05.2f' %k+'_kd_%05.2f'%kd+'.png')
                plt.close()
                break
            del res,P16,P25,P50,P75,P84



            kd+=.01

        k*=1.025
def grid_table(N,narr,snarr,sdarr,directory):
    if directory[-1]=='/':
        pass
    else:
        directory+='/'

    NN=len(narr)*len(snarr)*len(sdarr)
    ii=-1
    n=np.zeros(NN)
    R=np.zeros(NN)
    D=np.zeros(NN)
    A=np.zeros(NN)
    mu=np.zeros(NN)
    sig=np.zeros(NN)

    for nd in narr:
        for S_noise in snarr:
            if os.path.isfile(directory+'noise_N%04d'%N+'_n%.1f'%nd+'_R%03d'%S_noise+'.npy'):
                Vort=np.load(directory+'noise_N%04d'%N+'_n%.1f'%nd+'_R%03d'%S_noise+'.npy')
            else:
                Vort=example(N,nd,S_noise,directory)
            for sd in sdarr:
                ii+=1

                n[ii]=nd
                R[ii]=S_noise
                D[ii]=sd
                temp='%02d'%sd
                if os.path.isfile(directory+'difussion_N%04d'%N+'_n%.1f'%nd+'_R%03d'%S_noise+'_D'+temp+'.npy'):
                    Vort2=np.load(directory+'difussion_N%04d'%N+'_n%.1f'%nd+'_R%03d'%S_noise+'_D'+temp+'.npy')
                else:
                    Vort2=difussion(Vort,sd,mode='wrap')
                res,Neg=Circulation_Negative(Vort2)
                x=res[Neg>0]
                y=Neg[Neg>0]
                try:
                    f1=interp1d(y,x)
                    x50=f1(y[0]/2)
                    s=(x50-1)/(np.sqrt(2*np.log(2)))
                    popt, pcov = curve_fit(gaussian, x , y, p0=[y[0],x[0],s],bounds=(-np.inf,[np.inf,1,np.inf]))

                    A[ii]=popt[0]
                    mu[ii]=popt[1]
                    sig[ii]=popt[2]
                    del popt,pcov,s,x50,f1
                except:
                    A[ii]=0
                    mu[ii]=0
                    sig[ii]=0
                del res,Neg,x,y
                print(ii*100.0/NN)

    tabla=Table()
    tabla['n']=Column(n)
    tabla['R']=Column(R)
    tabla['D']=Column(D)
    tabla['A']=Column(A)
    tabla['mu']=Column(mu)
    tabla['sig']=Column(sig)
    tabla.write('Examples/Table_Parameters_Grid',path='data',format='hdf5',overwrite=True)
def optimum_turb_diff(name,log=True):
    if os.path.isfile(name+'_optimum_turb_diff'):
        print('File already exists')
        return 0

    Data=np.load(name+'_vort.npy')
    Data=Data[1:-1,1:-1]
    D05=np.percentile(Data.ravel(),0.5)
    D95=np.percentile(Data.ravel(),99.5)
    h1,b1=np.histogram(Data.ravel(),50,range=(D05,D95))
    del Data
    if log:
        h1[h1==0]=1
    k=0.5
    c1=1e10
    c2=1e9
    CMIN=1e10
    while c1>c2:
        c1=c2
        VORT=difussion_image(name,k)
        kd=0.025
        sup=1e10
        for kk in range(20):

            VORT2=difussion(VORT,kd,mode='wrap')
            h2,b2=np.histogram(VORT2.ravel(),50,range=(D05,D95))
            if log:
                h2[h2==0]=1
                c3=((np.log(h1)-np.log(h2))**2).sum()
            else:
                c3=((h1-h2)**2).sum()/1e10

            if c3<sup:
                sup=c3
                KD=kd
            kd+=0.025
            del VORT2
        c2=sup

        if c2<CMIN:
            CMIN=c2
            KTM=k
            KDM=KD
        k+=0.2
    return KTM,KDM
def apply_temp(name,KT,KD,ij,Nbins):

    kt      = KT[ij]
    kd      = KD[ij]
    temp    = np.load(name+'_temp_%07.2f' %kt+'.npy')
    temp2   = difussion(temp,kd,mode='wrap')
    temp3   = np.zeros_like(temp2)
    N       = len(temp2)
    radial  = radial_map(temp2)

    del temp

    if Nbins>1:
        redges = np.linspace(0,0.5*N,Nbins)
        redges = np.insert(redges,len(redges),radial.max())
    else:
        redges=np.array([0,radial.max()])

    ring    = (redges[ij]<radial)&(radial<redges[ij+1])
    temp3[ring]=temp2[ring]
    return temp3
def save_example(N,n,S_noise,S_diff,directory):
    if directory[-1]=='/':
        pass
    else:
        directory+='/'
    if os.path.isfile(directory+'noise_N%04d'%N+'_n%.1f'%n+'_R%03d'%S_noise+'.npy'):
        print('noise file exists',N,n,S_noise)
        Vort2=np.load(directory+'noise_N%04d'%N+'_n%.1f'%n+'_R%03d'%S_noise+'.npy')
    else:
        Vort2=example(N,n,S_noise,directory)
        np.save(directory+'noise_N%04d'%N+'_n%.1f'%n+'_R%03d'%S_noise,Vort2)
    if S_diff=='None':
        pass
    else:
        for sd in S_diff:
            if os.path.isfile(directory+'difussion_N%04d'%N+'_n%.1f'%n+'_R%03d'%S_noise+'_D'+temp+'.npy'):
                pass
            else:
                Vort=difussion(Vort2,sd,mode='wrap')
                temp='%02d'%sd
                np.save(directory+'difussion_N%04d'%N+'_n%.1f'%n+'_R%03d'%S_noise+'_D'+temp,Vort)
                del Vort
    return True
def optimum_turb_diff_radii(name,Nbins,log=True):
    if os.path.isfile(name+'turb-diff-%04d'%Nbins):
        print('File already exists')
        return 0
    N=Nbins
    k=0.5
    counter=0
    Data=np.load(name+'_vort.npy')
    Data=Data[1:-1,1:-1]
    xmax,ymax=np.shape(Data)

    X=np.array(list(np.reshape(range(xmax),(1,xmax)))*xmax)

    Y=X.T
    X=np.reshape(X,(xmax,xmax))-np.mean(X)
    Y=np.reshape(Y,(xmax,xmax))-np.mean(Y)
    R=np.sqrt(X**2+Y**2)
    Data=Data.ravel()
    R=R.ravel()
    rmin=R.min()
    rmax=R.max()/np.sqrt(2)
    Redges=np.linspace(rmin,rmax,N+1)
    Rcen=0.5*(Redges[1:]+Redges[:-1])
    B1=1e10*np.ones(N)
    B2=1e9*np.ones(N)
    KTM=np.zeros(N)
    KDM=np.zeros(N)
    CMIN=1e10*np.ones(N)
    while counter < N:

        VORT=difussion_image(name,k)


        for i in range(N):
            region=((R>Redges[i])&(R<Redges[i+1]))
            lim_inf=np.percentile(Data[region],0.5)
            lim_sup=np.percentile(Data[region],99.5)
            h1,b1=np.histogram(Data[region],50,range=(lim_inf,lim_sup))
            if log:
                h1[h1==0]=1

            B1[i]=B2[i]
            kd=0.025
            sup=1e10
            for kk in range(100):
                VORT2=difussion(VORT,kd,mode='wrap')
                h2,b2=np.histogram(VORT2.ravel(),50,range=(lim_inf,lim_sup))
                if log:
                    h2[h2==0]=1
                    c3=((np.log(h1)-np.log(h2))**2).sum()
                else:
                    c3=((h1-h2)**2).sum()

                if c3<sup:
                    sup=c3
                    KD=kd
                kd+=0.025
                del VORT2

            B2[i]=sup
            if B2[i]<CMIN[i]:
                CMIN[i]=B2[i]
                KTM[i]=k
                KDM[i]=KD
            del sup
            k+=0.2

            if (B2[i]>B1[i]):
                counter+=1

    return [KTM,KDM,Rcen,40000/(xmax+2)]
def apply_turb_diff(name,KTM,KDM):
    VORT=difussion_image(name,KTM)
    VORT=difussion(VORT,KDM,mode='wrap')
    return VORT
def Circulation_negative_optimum_thread(name,k):
    print('Circulation_negative_optimum_thread')
    Data=np.load(name+'_vort.npy')
    dx0=4.0e4/len(Data)

    tab=Table.read('Circulation_data/Full-Percentiles/Negative/'+name+'-Negative',path='data')
    r0=tab['Resolution']*2
    N0=tab['Number']

    r0=np.insert(r0,0,0)
    r0=np.insert(r0,len(r0),1.0e5)
    N0=np.insert(N0,0,N0[0])
    N0=np.insert(N0,len(N0),0)
    Ne=interp1d(r0,N0)
    kd1=1
    kd2=50

    print('kt =',k)
    VORT=difussion_image(name,k)

    N1=scaling(VORT,kd1)-N0[0]
    N2=scaling(VORT,kd2)-N0[0]
    if N1*N2<0:
        thresh=1e3
        while thresh>2e-3:
            aux=scaling(VORT,0.5*(kd2+kd1))-N0[0]

            if N1*aux<0:
                kd2=0.5*(kd2+kd1)
            else:
                kd1=0.5*(kd2+kd1)

            thresh=np.abs((1-kd2/kd1)/(1+kd2/kd1))

        VORT2=difussion(VORT,kd2,mode='wrap')
        res,Neg=Circulation_Negative(VORT2)
        res=res*dx0
        aNeg=Ne(res)
        XMAX=max(res[np.where(Neg>0)].max(),res[np.where(aNeg>0)].max())
        XMIN=max(res[np.where(Neg>0)].min(),res[np.where(aNeg>0)].min())
        xnew=np.exp(np.linspace(np.log(XMIN),np.log(XMAX),1000))
        fy=interp1d(res,Neg)
        fz=interp1d(res,aNeg)
        ynew=fy(xnew)
        znew=fz(xnew)
        ynew*=znew[0]/ynew[0]
        err=(ynew-znew)**2
        err=np.sqrt(np.mean(err))

        n_slope=get_slope(name,0,1.5e4)
        plt.plot(tab['Resolution']*2,tab['Number'])
        x=tab['Resolution']
        y=tab['Number']
        x=x[y>0]
        y=y[y>0]
        dx=x[0]
        x=2*x/dx
        f1=interp1d(y,x)
        x50=f1(y[0]/2)
        s=(x50-1)/(np.sqrt(2*np.log(2)))
        popt, pcov = curve_fit(gaussian, x , y, p0=[y[0],x[0]/2.0,s],bounds=(-np.inf,[np.inf,1.01,np.inf]))
        plt.plot(res,gaussian(res/dx0,*popt),'k-.')
        print(*popt)
        print(prediction_negative_n(*popt,n_slope))
        plt.plot(res,Neg,color="#38c3ff",linestyle=':')
        plt.xscale('log')
        plt.title('error_%08.4f' %err)
        plt.axvline(kd2*dx,color='k',linestyle=':')
        plt.xlim(30,5e3)
        plt.savefig('Temp_Files/Figures/Negative_kt_%06.2f' %k+'_kd_%05.2f'%kd2+'.png')
        plt.close()


    return kd2,err
def Circulation_negative_optimum_dispersion(name):

    Data=np.load(name+'_vort.npy')
    dx=4.0e4/len(Data)

    tab=Table.read('Circulation_data/Percentiles/Negative/NWR10025-Negative',path='data')
    r0=tab['Resolution']
    N0=tab['Number']

    r0=np.insert(r0,0,0)
    r0=np.insert(r0,len(r0),1.0e5)
    N0=np.insert(N0,0,N0[0])
    N0=np.insert(N0,len(N0),0)
    Ne=interp1d(r0,N0)

    k=1


    minimo=1e10
    while k<25:
        kd1=1
        kd2=30
        VORT=dispersion_image(name,k,150)

        N1=scaling(VORT,kd1)-N0[0]
        N2=scaling(VORT,kd2)-N0[0]
        print(k,kd1,kd2,N1,N2)
        if N1*N2<0:
            switch=True
            thresh=1e3
            while thresh>2e-3:
                aux=scaling(VORT,0.5*(kd2+kd1))-N0[0]

                if N1*aux<0:
                    kd2=0.5*(kd2+kd1)
                else:
                    kd1=0.5*(kd2+kd1)

                thresh=np.abs((1-kd2/kd1)/(1+kd2/kd1))

            VORT2=difussion(VORT,kd2,mode='wrap')
            res,Neg=Circulation_Negative(VORT2)
            res=res*dx
            err=(Neg-Ne(res))**2
            err=np.sqrt(np.mean(err))

            if err<minimo:
                minimo=err
            else:
                break
            plt.plot(tab['Resolution'],tab['Number'])

            plt.plot(res,Neg,color="#38c3ff",linestyle=':')
            plt.xscale('log')
            plt.title('error_%08.4f' %err)
            plt.axvline(kd2*dx,color='k',linestyle=':')


            plt.savefig('Temp_Files/Figures/Negative_kt_%06.2f' %k+'_kd_%05.2f'%kd2+'.png')
            plt.close()

            kd1=kd1/1.2
            kd2=kd2*1.2

        k+=0.1
def Circulation_negative_fits(name,k,Nbins,start):
    print('KT = ',k)
    Data=np.load(name+'_vort.npy')
    dx=4.0e4/len(Data)

    kd=start

    #print('applying noise')
    VORT=difussion_image(name,k)
    switch =-1*np.ones(Nbins)
    kdarray=np.zeros(Nbins)
    erarray=np.zeros(Nbins)
    while switch.sum()<Nbins:
        VORT1=difussion(VORT,kd,mode='wrap')
        res,rcen,Neg,redges=Circulation_Negative_radii(VORT1,Nbins)
        for j in range(Nbins):

            x,y=interp_negative_bin(name,dx*redges[j],dx*redges[j+1])
            if (Neg[j,:][0]-y[0]<0) & (switch[j]<0):
                switch[j]=1
                kdarray[j]=kd
                raux=res*dx
                Naux=Neg[j,:]
                raux=np.insert(raux,0,0)
                Naux=np.insert(Naux,0,Naux[0])
                func=interp1d(raux,Naux)
                z=func(x)
                XMAX=max(x[np.where(y>0)].max(),x[np.where(z>0)].max())
                XMIN=max(x[np.where(y>0)].min(),x[np.where(z>0)].min())
                xnew=np.exp(np.linspace(np.log(XMIN),np.log(XMAX),100))
                fy=interp1d(x,y)
                fz=interp1d(x,z)
                ynew=fy(xnew)
                znew=fz(xnew)
                znew*=ynew[0]/znew[0]
                err=(znew-ynew)**2
                err=np.mean(err)
                err=np.sqrt(err)
                erarray[j]=err


                plt.title('error_%08.4f' %err)
                plt.plot(x,y,'b-')
                plt.plot(x,z*y[0]/z[0],'r:')

                x=x[y>0]
                y=y[y>0]
                dx=x[0]
                x=x/dx
                f1=interp1d(y,x)
                x50=f1(y[0]/2)
                s=(x50-1)/(np.sqrt(2*np.log(2)))
                popt, pcov = curve_fit(gaussian, x , y, p0=[y[0],x[0],s],bounds=(-np.inf,[np.inf,1.01,np.inf]))
                plt.plot(res,gaussian(res/dx,*popt),'k-.')
                print(j,prediction_negative(*popt)[1])
                plt.xscale('log')
                plt.xlim(30,5e3)
                #plt.yscale('log')
                plt.ylim(ymin=0.0)
                plt.savefig('Temp_Files/Figures/Negative_j_%02d' %j +'_kt_%06.2f' %k+'_kd_%05.2f'%kd+'.png')
                plt.close()

                del raux,Naux,err,z

        kd+=0.1
    start=kdarray.min()
    return kdarray , erarray ,rcen*dx
def Circulation_negative_optimum(name,kmin,kmax,Nk):
    print('Circulation_negative_optimum')
    Data=np.load(name+'_vort.npy')
    dx=4.0e4/len(Data)

    tab=Table.read('Circulation_data/Full-Percentiles/Negative/'+name+'-Negative',path='data')
    r0=tab['Resolution']
    N0=tab['Number']

    r0=np.insert(r0,0,0)
    r0=np.insert(r0,len(r0),1.0e5)
    N0=np.insert(N0,0,N0[0])
    N0=np.insert(N0,len(N0),0)
    Ne=interp1d(r0,N0)
    karray=np.exp(np.linspace(np.log(kmin),np.log(kmax),Nk))
    kd1=1
    kd2=50
    KD=[]
    factor=karray[1]/karray[0]
    minimo=1e10
    for nk,k in enumerate(karray):
        print('kt =',k)
        VORT=difussion_image(name,k)

        N1=scaling(VORT,kd1)-N0[0]
        N2=scaling(VORT,kd2)-N0[0]
        if N1*N2<0:
            thresh=1e3
            while thresh>2e-3:
                aux=scaling(VORT,0.5*(kd2+kd1))-N0[0]

                if N1*aux<0:
                    kd2=0.5*(kd2+kd1)
                else:
                    kd1=0.5*(kd2+kd1)

                thresh=np.abs((1-kd2/kd1)/(1+kd2/kd1))

            VORT2=difussion(VORT,kd2,mode='wrap')
            res,Neg=Circulation_Negative(VORT2)
            res=res*dx
            err=(Neg-Ne(res))**2
            err=np.sqrt(np.mean(err))
            KD.append(kd2)
            if err<minimo:
                minimo=err
            else:
                break
            if k==karray.max():
                break
            plt.plot(tab['Resolution'],tab['Number'])

            plt.plot(res,Neg,color="#38c3ff",linestyle=':')
            plt.xscale('log')
            plt.title('error_%08.4f' %err)
            plt.axvline(kd2*dx,color='k',linestyle=':')
            plt.xlim(30,5e3)

            plt.savefig('Temp_Files/Figures/Negative_kt_%06.2f' %k+'_kd_%05.2f'%kd2+'.png')
            plt.close()

            kd1=kd1/(1+factor*2)
            kd2=kd2*(1+factor*2)
    return karray[nk-1],KD[-2]
def scaling(VORT,kd):
    VORT2=difussion(VORT,kd,mode='wrap')

    res,Neg=Circulation_Negative(VORT2)

    return Neg[0]