Exemple #1
0
def mieMonteCarlo(wavelength=450 * 10**-9,
                  r=300 * 10**-9,
                  Vs=0.1,
                  nParticle=1.46,
                  nMedium=1.36):
    """
    Calculate the scattering parameters relevant for monte carlo simulation.

    Needs pymiecoated: https://code.google.com/p/pymiecoated/
    These are calculate scattering coefficient [1/cm] and anisotropy factor for given:

    Args
    ____
    wavelength:
        wavelength of the incident light [m]
    r:
        radius of the particle [m]
    Vs:
        volume fraction of scattering particles
    nParticle:
        refractive index of the particle that the light wave is scattered on
        (default value is the refractive index of collagen)
    nMedium:
        refractive index of the surronding medium (default is that of colonic
        mucosal tissue)

    Returns:
    ____
    {'us', 'g'}:
        scattering coefficient us [1/m] and anisotropy factor g

    TODO:
    _____
        Additional input parameter specifying a FWHM for the wavelength to simulate the
        scattering for a broad filter
    """

    # create derived parameters
    sizeParamter = 2 * math.pi * r / wavelength
    nRelative = nParticle / nMedium

    #%% execute mie and create derived parameters

    mie = Mie(x=sizeParamter, m=complex(nRelative,
                                        0.0))  # 0.0 complex for no attenuation

    A = math.pi * r**2  # geometrical cross sectional area
    cs = mie.qsca() * A  # scattering cross section

    us = Vs / (4 / 3 * r**3 * math.pi) * cs  # scattering coefficient [m⁻1]

    return {'us': us, 'g': mie.asy()}
Exemple #2
0
def mieMonteCarlo(wavelength = 450*10**-9, r = 300*10**-9, Vs = 0.1, nParticle = 1.46, nMedium = 1.36):
    """
    Calculate the scattering parameters relevant for monte carlo simulation.

    Needs pymiecoated: https://code.google.com/p/pymiecoated/
    These are calculate scattering coefficient [1/cm] and anisotropy factor for given:

    Args
    ____
    wavelength:
        wavelength of the incident light [m]
    r:
        radius of the particle [m]
    Vs:
        volume fraction of scattering particles
    nParticle:
        refractive index of the particle that the light wave is scattered on
        (default value is the refractive index of collagen)
    nMedium:
        refractive index of the surronding medium (default is that of colonic
        mucosal tissue)

    Returns:
    ____
    {'us', 'g'}:
        scattering coefficient us [1/m] and anisotropy factor g

    TODO:
    _____
        Additional input parameter specifying a FWHM for the wavelength to simulate the
        scattering for a broad filter
    """

    # create derived parameters
    sizeParamter = 2 * math.pi * r / wavelength
    nRelative    = nParticle / nMedium

    #%% execute mie and create derived parameters

    mie = Mie(x=sizeParamter, m=complex(nRelative,0.0))  # 0.0 complex for no attenuation

    A  = math.pi * r**2 # geometrical cross sectional area
    cs = mie.qsca() * A # scattering cross section

    us = Vs / (4/3 * r**3 * math.pi) * cs # scattering coefficient [m⁻1]

    return {'us': us, 'g': mie.asy()}
Exemple #3
0
    for nband in range(len(wavmin)):
        specbin = np.linspace(wavmin[nband], wavmax[nband], 50)
        for db in range(len(Deff)):
            qext = 0.
            ssa = 0.
            asy = 0.

            for wl in range(len(specbin)):
                sp = np.pi * Deff[db] / specbin[wl]
                k = kint(specbin[wl])
                nd = ndint(specbin[wl])
                mie = Mie(x=sp, m=complex(nd, k))
                qext = qext + mie.qsca() + mie.qabs()
                qabs = mie.qabs()
                ssa = ssa + mie.qsca() / (mie.qsca() + mie.qabs())
                asy = asy + mie.asy()
            extb[db, nband] = extb[db, nband] + (qext / len(specbin)) / (
                2. / 3. * rhop * Deff[db] * 1E-6)
            #cross section in m2/g
            ssab[db, nband] = ssab[db, nband] + (ssa / len(specbin))
            asyb[db, nband] = asyb[db, nband] + (asy / len(specbin))

if (1 == 2):
    #method 2(slower) double integration  /more precise prblem mie return nan for extrem coarse particles
    # calculate the mie parameter for every diameter of the range, averaged on spectral band

    extb = np.zeros((len(sbin) - 1, len(wavmin)))
    ssab = np.zeros((len(sbin) - 1, len(wavmin)))
    asyb = np.zeros((len(sbin) - 1, len(wavmin)))

    for nband in range(len(wavmin)):
Exemple #4
0
def get_optical_properties(rhop, filename):

    # user defined parameter
    #define the number (or mass) distribution (e.g from Kok et al).
    #diameter micron
    D = np.arange(0.001, 20, 0.005)

    if (1 == 2):
        D = np.arange(0.01, 65, 0.05)
    if (1 == 1):
        cN = 0.9539
        Ds = 3.4
        sigs = 3.0
        lamb = 12
        A = np.log(D / Ds) / (np.sqrt(2) * np.log(sigs))
        #care dND/dD or dND/d(lnD) !!
        dND = (1 / D) * (1 /
                         (cN * D * D)) * (1 + erf(A)) * np.exp(-1. *
                                                               (D / lamb)**3)
        #dND = (D/12.62) * (1 + erf(A)) * np.exp(-1.*(D/lamb)**3)

    # here use a 3 log distribution
    # e.g. alfaro Gomez
    if (1 == 2):
        sig = [1.75, 1.75, 1.75]
        Dm = [0.64, 3.45, 8.67]
        Nf = [0.74, 0.20, 0.06]
        dND = ddlogn(D, Dm, sig, Nf)

    if (1 == 1):
        #define 2 size bins for each SOA category
        sbin = np.array([0.001, 0.03, 0.70])

    if (1 == 2):
        #define the 12 new size bin cut of diam from LISA optimised distribution
        #you can take also one big bin encompassing the whole distrib (that 's what
        #we do for BC/OC, in this case it is equivalent to integrate over the full
        #distrib mode).

        #here is LISA optimal distrib for dust
        sbin =  np.array([0.09,0.18, 0.6, 1.55, 2.50, 3.75, 4.70, 5.70, 7.50,\
                           14.50, 26.0, 41.0, 63.0])
        #sbin = [0.01 ,1.,2.5,5.,20. ]
        #sbin =[0.98,1.2,2.5,5.,20.]

    ## Uncomment the following line for testing
    # rhop, ndbib, wbib, kbib = return_test_variables()

    wbib, ndbib, kbib = np.loadtxt(soa_ri_path + filename,
                                   skiprows=0,
                                   unpack=True)

    #kbib = [0.04, 0.027866667,     0.020111111,    0.014933333,    0.001,    0.001,    0.001,    0.001,    0.003177778,    0.003033333,    0.003011111,    0.002911111,    0.003111111,    0.003111111,    0.003066667 , 0.0028,0.0025,0.002, 0.00195, 0.0019]

    #with this function we can simply interpolate kbib for every value of wavelenght !
    kint = interp1d(wbib, kbib, kind='linear')
    ndint = interp1d(wbib, ndbib, kind='linear')

    #########
    # define the spectral band ( wavmin and wavemax) of the radiation model
    # here from radiation RegCM standard regcm code

    wavmin = [
        0.2000, 0.2450, 0.2650, 0.2750, 0.2850, 0.2950, 0.3050, 0.3500, 0.6400,
        0.7000, 0.7010, 0.7010, 0.7010, 0.7010, 0.7020, 0.7020, 2.6300, 4.1600,
        4.1600
    ]

    wavmax = [
        0.2450, 0.2650, 0.2750, 0.2850, 0.2950, 0.3050, 0.3500, 0.6400, 0.7000,
        5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 5.0000, 2.8600, 4.5500,
        4.5500
    ]
    #num = 7 for visible band standard scheme
    num = 7
    ## si RRTM set 1 == 1 to overwrite
    #if(1==2):
    #    # RRTM Shortwave spectral band limits (wavenumbers)
    #    #wavenum are in cm-1 / take the inverse for wavelenght
    #    wavenum1 =  np.array([2600., 3250., 4000., 4650., 5150., 6150., 7700., \
    #                          8050.,12850.,16000.,22650.,29000.,38000.,  820.])
    #    wavenum2 =  np.array([3250., 4000., 4650., 5150., 6150., 7700., 8050., \
    #                         12850.,16000.,22650.,29000.,38000.,50000., 2600.])
    #
    ## Longwave spectral band limits (wavenumbers)
    #    if(1==2):
    #       wavenum1 =  np.array([ 10., 350., 500., 630., 700., 820., \
    #                      980. ,1080. ,1180. ,1390. ,1480. ,1800. , \
    #                     2080. ,2250. ,2380. ,2600. ])
    #       wavenum2 =  np.array([350. , 500. , 630. , 700. , 820. , 980. , \
    #                     1080. ,1180. ,1390. ,1480. ,1800. ,2080. , \
    #                     2250. ,2380. ,2600. ,3250. ])
    ## determined from indica marc for the longwave
    #       wbib=  [3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 20, 30, 1100]
    #       kbib = [7.54E-2, 5.14E-2, 5.94E-2, 1.41E-1, 1.46E-1, 2.18E-1, \
    #                    5.35E-1, 3.70E-1, 1.18E-1,  2.28E-1, 2.79E-1, 6.12E-1,\
    #                    4.95E-1, 6.50E-1 ]
    #       nbib =   [1.49,  1.51,  1.58, 1.45,  1.46, 1.19,  1.86, 1.84, 1.78, \
    #                    1.65,  1.55,  2.25, 2.40, 2. ]
    #       kint = interp1d(wbib,kbib,kind='linear')
    #       ndint = interp1d(wbib,nbib,kind='linear')
    #    #convert to wavelenght in micron
    #    # visible is index
    #    wavmin  = np.power(wavenum2*1.E-4,-1.)
    #    wavmax  = np.power(wavenum1*1.E-4,-1.)
    #
    #    if (1==1):
    #       num = 7 # for visible band standard scheme
    #    if (1==2):
    #       num = 9 # for vis RRTM

    #print num

    #print wavmin
    #print wavmax

    # end of user deined parameter
    ##################################################################
    ####################################################################3

    # 1) calculate the effective radius of each bin (used in regcm )
    Sv = np.zeros(len(sbin) - 1)
    Ss = np.zeros(len(sbin) - 1)
    normb = np.zeros(len(sbin) - 1)

    for b in range(len(sbin) - 1):
        for dd in range(len(D)):
            if (D[dd] >= sbin[b] and D[dd] < sbin[b + 1]):
                Sv[b] = Sv[b] + D[dd]**3 * dND[dd]
                Ss[b] = Ss[b] + D[dd]**2 * dND[dd]
                normb[b] = normb[b] + dND[dd]
    Deff = Sv / Ss
    print Deff

    ## visu
    #
    #fig = plt.figure()
    #ax = fig.add_subplot(1,3,1)
    ##here plot dN/d(logD) !!
    #ax.plot(D,dND *D , color='blue')
    #ax.set_yscale('log')
    #ax.set_xscale('log')
    #ax.set_xlim([0.08, 65])
    #ax.set_ylim([1.E-4, 1])
    #ax.set_title("distribution and bins, dot= Deff")
    #ax.set_xlabel('D in micrometer')
    #plot also bin end effrad
    #for x in sbin:
    # ax.plot([x, x],[1.E-4, 1], color='black')
    #for x in Deff:
    # ax.scatter(x,2E-4, color='green')
    #
    #
    ##visu also the ref index spectral variation interp + values
    #ax2 = fig.add_subplot(1,3,2)
    ##xx = np.linspace(0.2,13,500)
    #xx = np.linspace(3,40,500)
    #ax2.plot(xx, ndint(xx), color='green')
    ##ax2.scatter(wbib,kbib)
    #ax2.set_title(" im ref index, dot = data, line = interp used for oppt calc. ")
    #ax2.set_xlabel('wavelenght in micrometer')

    #2  mie calculation
    ######################################
    #calculate optical properties per bin
    #######################################3
    # methode 1 considering only bin effective diam calculated before
    if (1 == 1):
        extb = np.zeros((len(sbin) - 1, len(wavmin)))
        ssab = np.zeros((len(sbin) - 1, len(wavmin)))
        asyb = np.zeros((len(sbin) - 1, len(wavmin)))
        for nband in range(len(wavmin)):
            specbin = np.linspace(wavmin[nband], wavmax[nband], 50)
            for db in range(len(Deff)):
                qext = 0.
                ssa = 0.
                asy = 0.

                for wl in range(len(specbin)):
                    sp = np.pi * Deff[db] / specbin[wl]
                    k = kint(specbin[wl])
                    nd = ndint(specbin[wl])
                    mie = Mie(x=sp, m=complex(nd, k))
                    qext = qext + mie.qsca() + mie.qabs()
                    qabs = mie.qabs()
                    ssa = ssa + mie.qsca() / (mie.qsca() + mie.qabs())
                    asy = asy + mie.asy()
                extb[db, nband] = extb[db, nband] + (qext / len(specbin)) / (
                    2. / 3. * rhop * Deff[db] * 1E-6)
                #cross section in m2/g
                ssab[db, nband] = ssab[db, nband] + (ssa / len(specbin))
                asyb[db, nband] = asyb[db, nband] + (asy / len(specbin))

    if (1 == 2):
        #method 2(slower) double integration  /more precise prblem mie return nan for extrem coarse particles
        # calculate the mie parameter for every diameter of the range, averaged on spectral band

        extb = np.zeros((len(sbin) - 1, len(wavmin)))
        ssab = np.zeros((len(sbin) - 1, len(wavmin)))
        asyb = np.zeros((len(sbin) - 1, len(wavmin)))

        for nband in range(len(wavmin)):
            specbin = np.linspace(wavmin[nband], wavmax[nband], 10)
            extd = np.zeros(len(D))
            ssad = np.zeros(len(D))
            asyd = np.zeros(len(D))
            for db in range(len(D)):
                qext = 0.
                ssa = 0.
                asy = 0.
                for wl in range(len(specbin)):
                    sp = np.pi * D[db] / specbin[wl]
                    k = kint(specbin[wl])
                    nd = ndint(specbin[wl])
                    mie = Mie(x=sp, m=complex(nd, k))
                    qext = qext + mie.qsca() + mie.qabs()
                    ssa = ssa + mie.qsca() / (mie.qsca() + mie.qabs())
                    asy = asy + mie.asy()
                extd[db] = qext / len(specbin) / (2. / 3. * rhop * D[db] *
                                                  1E-6)
                ssad[db] = ssa / len(specbin)
                asyd[db] = asy / len(specbin)
            # perform the bin wighting av according to distibution
            for b in range(len(sbin) - 1):
                if (D[db] >= sbin[b] and D[db] < sbin[b + 1]):
                    extb[b,
                         nband] = extb[b,
                                       nband] + extd[db] * dND[db] / normb[b]
                    ssab[b,
                         nband] = ssab[b,
                                       nband] + ssad[db] * dND[db] / normb[b]
                    asyb[b,
                         nband] = asyb[b,
                                       nband] + asyd[db] * dND[db] / normb[b]

    # 3  nan out for the big bin which can have nan values ....
    # the kext is set  very low which means that the bin won't matter much in the rad
    extb[np.isnan(extb)] = 1.E-20
    asyb[np.isnan(asyb)] = 0.99
    ssab[np.isnan(ssab)] = 0.5

    print "extb vis", extb[:, num]
    print "ssab vis", ssab[:, num]
    print "asyb vis", asyb[:, num]
    #print "absb vis", extb[:,num] * ssab[:,num]

    ##4 visu  oppt / bin
    #
    #ax3 = fig.add_subplot(1,3,3)
    #xx = np.linspace(0.2,4,500)
    #ax3.set_xlim([0.08,65 ])
    #ax3.set_ylim([0, 5])
    #for n in range(len(sbin)-1):
    # ax3.plot([sbin[n], sbin[n+1]],[extb[n,num],extb[n,num]], color='black')
    # ax3.plot([sbin[n], sbin[n+1]],[ssab[n,num],ssab[n,num]], color='blue')
    # ax3.plot([sbin[n], sbin[n+1]],[asyb[n,num],asyb[n,num]], color='red')
    #
    #ax3.set_title(" bin oppt vis: blk:kext, blue:ssa, red:asy ")
    #ax3.set_xscale('log')
    #ax3.set_xlabel('D in micrometer')

    # finally  save in afile in a format close to mod_rad_aerosol block data
    # will just need copy paste + a few edit for fortan
    # file = open("aeroppt_blocl.txt", "w")
    compound = os.path.splitext(os.path.basename(filename))[0]
    np.savetxt(compound + '_Deff.txt', Deff, fmt='%7.5E', delimiter=', ')
    np.savetxt(compound + '_extb.txt', extb, fmt='%7.5E', delimiter=', ')
    np.savetxt(compound + '_ssab.txt', ssab, fmt='%7.5E', delimiter=', ')
    np.savetxt(compound + '_asyb.txt', asyb, fmt='%7.5E', delimiter=', ')