https://github.com/SimonUnterstrasser/ColumnModel
Raw File
Tip revision: 8c4e8c105fdfa552938c3dcbe71de99be72243f3 authored by SimonUnterstrasser on 15 September 2020, 15:26:46 UTC
Update README.md
Tip revision: 8c4e8c1
Misc.nogcc.py
import numpy as np

"""
Mapping SIP to Bin
"""

#Mapping of SIP ensemble onto a bin grid
#SIP ensemble (of one realisation) with nr_SIPs SIP defined by nEK_sip and mEK_sip
#Properties of the bin grid are specified by n10_plot, r10_plot, min10_plot

def MapSIPBin(nEK_sip,mEK_sip,nr_SIPs,n10,r10,min10):
    n= n10 * r10
    mfix=np.zeros(n)
    mdelta=np.zeros(n)
    mfix[0]=10**(min10)
    for i in range(1,n):
        mfix[i]=10**((i-1)/n10+min10)
        mdelta[i-1]=mfix[i]-mfix[i-1]
    if (mfix[-1] < max(mEK_sip[0:nr_SIPs])):
        print("Note that the defined bin grid does not cover the full SIP ensemble ", mfix[-1] , max(mEK_sip[0:nr_SIPs]))

    #sort SIPs by size and check to which bin each SIP contributes
    z=1
    mEK_bin_tot=np.zeros(n)
    nEK_bin_ord=np.zeros(n)
    nEK_sip_tmp=nEK_sip[0:nr_SIPs]
    mEK_sip_tmp=mEK_sip[0:nr_SIPs]

    per=np.argsort(mEK_sip_tmp)

    for i in range(0,nr_SIPs):
        while(mfix[z]<mEK_sip_tmp[per[i]]):
            z=z+1

        nEK_bin_ord[z-1]=nEK_bin_ord[z-1]+nEK_sip_tmp[per[i]]/mdelta[z-1]
        #Hier entweder Binmittelpunkte (bei log muss noch mfix[i]=10^((i-1+0.5)/n10+min10)) oder so aehnlich abgeaendert werden
        if(nEK_bin_ord[z-1]!=0):
            mEK_bin_tot[z-1]=mEK_bin_tot[z-1]+nEK_sip_tmp[per[i]]*mEK_sip_tmp[per[i]]
        else:
            mEK_bin_tot[z-1]=(mfix[z]-mfix[z-1]/2)+mfix[z-1]

    mEK_bin_ord=np.zeros(n)
    for i in range(0,n):
        if(nEK_bin_ord[i]!=0):
            mEK_bin_ord[i]=mEK_bin_tot[i]/(nEK_bin_ord[i]*mdelta[i])
    return nEK_bin_ord,mEK_bin_ord,mEK_bin_tot,mdelta,z

#end subroutine MapSIPBin(nEK_sip,mEK_sip,nr_SIPs,n10,r10,min10):

def CountSIPs(nEK_sip,mEK_sip,nr_SIPs,nplot):
    # only for discrete applications with integer weights
    nEK_bin_plot=np.zeros(nplot)
    #print(max(mEK_sip),nplot)
    if (max(mEK_sip) > nplot):
        print('---------- Achtung: ', max(mEK_sip), nplot)
    for i in range(nr_SIPs):
        nEK_bin_plot[int(mEK_sip[i])-1] += nEK_sip[i]

    return nEK_bin_plot
#end subroutine CountSIPs(nEK_sip,mEK_sip,nr_SIPs,nplot)

def CIO_MOMmean(data_in=None,fp_in=None,fp_out=None,skal_m=1.0,dV=1.0,ikeep1D=None,igetSTD=0,iexcludetop=0):
    #CIO = "Compute or Input/Read mean Moments" and Output the data

    #Compute mean moments
    #Input: moment data of all realisations (given either by array data_in or read from files in folder  fp_in)
    #Output: return an array with averaged moments. Additionally write the data to a file, if  folder name fp_out is specified.

    #in box model simulations data_in.ndim is 3 and the average is taken over all instances => data_out.ndim=2
    #in colum model simulations data_in.ndim is 4
    #   if ikeep1D=None, take average over instances and column => data_out.ndim=2
    #   if ikeep1D=1,    take average over instances, produces mean vertical profiles of the moments => data_out.ndim=3

    #igetSTD = 1 return mean and standard deviation
    #igetSTD = 2 return and 10 and 90 percentile
    print('Compute mean moments')

    if (fp_in is not None):
        ndim_data=3
        fu = open(fp_in + 'Moments_meta.dat','r')
        dV = int(fu.readline())
        skal_m = int(fu.readline())
        nr_inst = int(fu.readline())
        nr_MOMsave = int(fu.readline())
        # in 1D read additional line with nz-value, then set ndim_data=4
        #t_vec_MOMsave= np.array(fu.readline().split(), dtype='float' )
        fu.close()
        fu = open(fp_in + 'Moments.dat','rb')
        data_in=np.loadtxt(fu).reshape((nr_inst,nr_MOMsave,4))
        fu.close()
        #print(data_in.shape)
    else:
        if (data_in is not None):
            ndim_data=data_in.ndim
            if (ndim_data == 3): [nr_inst,nt_MOMsave,nr_Mom]=data_in.shape
            if (ndim_data == 4): [nr_inst,nt_MOMsave,nz,nr_Mom]=data_in.shape
        else:
            print('supply either data or fp_in')


    if (ndim_data == 4 and ikeep1D is None):
        #case: column model data and compute totals over full column
        #two dimension is averaged over: over nr_inst and nz
        if (iexcludetop == 0):
            data_out_ColIntegr=np.mean(data_in,axis=2)  # additionally average over column
        else:
            nz_smallDom=int(nz/40*iexcludetop)
            print('nz_smallDom, nz: ', nz_smallDom, nz)
            data_out_ColIntegr=np.mean(data_in[:,:,:nz_smallDom,:],axis=2)  # additionally average over column
        data_out = np.mean(data_out_ColIntegr,axis=0)
        if (igetSTD == 1):
            MOM_StdDev = np.expand_dims(np.std(data_out_ColIntegr, axis=0), axis=0)
        if (igetSTD == 2):
            MOM_StdDev = np.abs(np.percentile(data_out_ColIntegr, [10,90], axis=0)-data_out) # given as positive deviations from the mean value
    else:
        #covers cases:
            # box model data
            # column model data, output are profiles
        data_out=np.mean(data_in,axis=0)
        if (igetSTD == 1):
            MOM_StdDev = np.expand_dims(np.std(data_in, axis=0), axis=0)
        if (igetSTD == 2):
            MOM_StdDev = np.abs(np.percentile(data_in, [10,90], axis=0)-data_out) # given as positive deviations from the mean value

    #print(data_out)
    if (fp_out is not None):
        fu = open(fp_out + 'MomentsMean.dat','wb')
        #data_in=np.savetxt(fu,data_out, fmt='%1.6e')
        np.savetxt(fu,data_out, fmt='%1.6e')
        fu.close()

    if (ndim_data == 4 and ikeep1D is not None):
        for i in range(4): data_out[:,:,i] = data_out[:,:,i]*skal_m**i/dV
    else:
        for i in range(4): data_out[:,i] = data_out[:,i]*skal_m**i/dV

    if (igetSTD > 0):
        return data_out, MOM_StdDev
    else:
        return data_out

def Moments(nr_inst,nEK_sip_ins,mEK_sip_ins,nr_moment):
    moment_inst=np.array(np.zeros(nr_inst))
    for k in range(0,nr_inst):
        moment_inst[k]=sum(nEK_sip_ins[k,:]*(mEK_sip_ins[k,:]**nr_moment))
    moment_all=sum(moment_inst[:])/nr_inst

    return moment_all, moment_inst

##############################################################################

def Moments_k0_3(nEK_sip_ins,mEK_sip_ins):
    moments_k=np.zeros(4)
    for k in range(0,4):
        moments_k[k]=sum(nEK_sip_ins*mEK_sip_ins**k)

    return moments_k
##############################################################################

def get_first_second_highest_SIPmass(mEK_sip_tmp):
    [nr_inst,nr_GVplot,nr_SIPs]= mEK_sip_tmp.shape
    maxM  = np.zeros([nr_inst,nr_GVplot])
    max2M = np.zeros([nr_inst,nr_GVplot])
    for i_time in range(nr_GVplot):
        for i_inst in range(nr_inst):
            max2M[i_inst,i_time], maxM[i_inst,i_time] = np.partition(mEK_sip_tmp[i_inst,i_time,:], -2)[-2:]

    maxM_mean  = np.mean(maxM,axis=0)
    max2M_mean = np.mean(max2M,axis=0)

    return maxM_mean, max2M_mean

def get_isep(zEK_sip_ins,zGBsep,nz):
    # works only, if a final SIP with z=zNan>zGBsep[nz] is present
    iSIP_GBsep = np.zeros(nz+1,dtype='int')
    nr_SIPs_GB = np.zeros(nz,dtype='int')
    iSIP=0
    iSIP_GBsep[0]=0
    #iz=0
    #print(iz,iSIP_GBsep[iz],zGBsep[iz])
    for iz in range(1,nz+1):
        while (zEK_sip_ins[iSIP] < zGBsep[iz]):
            iSIP+=1
        iSIP_GBsep[iz]=iSIP
        #print(iz,iSIP_GBsep[iz],zGBsep[iz])
    #print(iSIP_GBsep)
    nr_SIPs_GB = iSIP_GBsep[1:nz+1]-iSIP_GBsep[0:nz]
    #print(nr_SIPs_GB)
    return iSIP_GBsep,nr_SIPs_GB

def get_isep2(zEK_sip_ins,zGBsep,nz,nrSIPs):
    iSIP_GBsep = np.zeros(nz+1,dtype='int')
    nr_SIPs_GB = np.zeros(nz,dtype='int')
    iSIP=0
    iSIP_GBsep[0]=0
    iz=0
    #print(iz,iSIP_GBsep[iz],zGBsep[iz])
    for iz in range(1,nz+1):
        while (zEK_sip_ins[iSIP] < zGBsep[iz]):
            if (iSIP < nrSIPs-1):
                iSIP += 1
            else:
                break
        #print(iz,iSIP_GBsep[iz],zGBsep[iz])
        iSIP_GBsep[iz]=iSIP

    nr_SIPs_GB = iSIP_GBsep[1:nz+1]-iSIP_GBsep[0:nz]
    return iSIP_GBsep,nr_SIPs_GB

def m2r(mass_vec,const_mass2rad):
    #mass_vec  IN: mass in kg
    #         OUT: radius in m
    return (mass_vec*const_mass2rad)**(1./3.)

def r2m(r_vec,const_mass2rad):
    #mass_vec  IN: radius in m
    #         OUT: mass in kg
    return (r_vec**3.0)/const_mass2rad

def trackcenters(n,m,z,iSIP_GBsep,nr_SIPs_GB,nz,dz):
    # computes centroid of SIPs position inside grid boxes
    tmp   = np.zeros([2,nz,4])
    nom   = np.zeros([2,4])
    denom = np.zeros([2,4])
    for iz in range(0,nz):
        if (nr_SIPs_GB[iz] > 1):
            ia=iSIP_GBsep[iz]
            ie=iSIP_GBsep[iz+1]
            znorm= (z[ia:ie]/dz)-iz
            for iMom in range(4):
                weightIC=n[ia:ie]*(m[ia:ie]**iMom)
                weightSIP=m[ia:ie]**iMom
                a=(znorm*weightIC ).sum()
                b= weightIC.sum()
                c=(znorm*weightSIP).sum()
                d=weightSIP.sum()
                tmp[0,iz,iMom] = a/b
                tmp[1,iz,iMom] = c/d
                nom[0,iMom]+=a
                nom[1,iMom]+=c
                denom[0,iMom]+=b
                denom[1,iMom]+=d
    return tmp,nom,denom

def as_list(x):
    # converts, e.g., an integer value into an iterable list with a single integer value
    if type(x) is list:
        return x
    else:
        return [x]


def openfile(fn,options='r'):
    import os
    import gzip
    if os.path.isfile(fn+'.gz'):
        dat=gzip.open(fn+'.gz',options)
    elif os.path.isfile(fn):
        dat=open(fn,options)
    else:
        print('Datei nicht gefunden: ', fn+'(.gz)')
        return None
    return dat

def filename(fn,fn_base=''):
    import os
    igzip   = 0
    inormal = 0
    ifile = 0
    if os.path.isfile(fn_base+fn+'.gz'):
        igzip = 1
        ifile = 1
    if os.path.isfile(fn_base+fn):
        inormal = 1
        ifile = 2

    if (igzip + inormal == 2):
        'Both file types exist. Use Zip file (=1), use normal file (=2)'
        print(fn_base+fn)
        ifile = int(input("Both file types exist. Use Zip file (=1), use normal file (=2):  "))

    if (ifile > 0):
        suffix = [".gz",""]
        fn_return = fn+suffix[ifile-1]
        return fn_return

    print("File does not exist")
    fn_return = None
    return fn_return

def smooth(y, box_pts):
    #example call: plot(x, smooth(y,3), 'r-', lw=2)
    box = np.ones(box_pts)/box_pts
    y_smooth = np.convolve(y, box, mode='same')
    return y_smooth
back to top