Changeset 0076d6e in sasmodels


Ignore:
Timestamp:
Jul 5, 2018 7:22:13 PM (6 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
e262dd6
Parents:
757a3ff
Message:

clean up evaluation code; add Yun's gauss sphere examples

Location:
explore/beta
Files:
3 added
1 edited

Legend:

Unmodified
Added
Removed
  • explore/beta/sasfit_compare.py

    r757a3ff r0076d6e  
    170170    for k, qk in enumerate(q): 
    171171        r = sqrt(radius_equatorial**2*(1-((z+1)/2)**2)+radius_polar**2*((z+1)/2)**2) 
    172         F2i = ((sld-sld_solvent)*volume*sas_3j1x_x(qk*r))**2 
    173         F2[k] = np.sum(w*F2i) 
    174         F1i = (sld-sld_solvent)*volume*sas_3j1x_x(qk*r) 
    175         F1[k] = np.sum(w*F1i) 
     172        form = (sld-sld_solvent)*volume*sas_3j1x_x(qk*r) 
     173        F2[k] = np.sum(w*form**2) 
     174        F1[k] = np.sum(w*form) 
    176175    #the 1/2 comes from the change of variables mentioned above 
    177176    F2 = F2/2.0 
     
    205204    elif radius_equatorial_pd_type == 'schulz': 
    206205        Re_val, Re_prob = schulz_distribution(radius_equatorial, radius_equatorial_pd*radius_equatorial, 0, inf) 
    207     Normalization = 0 
    208     F1,F2 = np.zeros_like(q), np.zeros_like(q) 
    209     radius_eff = total_weight = 0 
     206    total_weight = total_volume = 0 
     207    radius_eff = 0 
     208    F1, F2 = np.zeros_like(q), np.zeros_like(q) 
    210209    for k, Rpk in enumerate(Rp_val): 
    211210        for i, Rei in enumerate(Re_val): 
    212211            theory = ellipsoid_theta(q,Rpk,Rei,sld,sld_solvent) 
    213212            volume = ellipsoid_volume(Rpk, Rei) 
    214             if norm == 'sasfit': 
    215                 Normalization += Rp_prob[k]*Re_prob[i] 
    216             elif norm == 'sasview' or norm == 'yun': 
    217                 Normalization += Rp_prob[k]*Re_prob[i]*volume 
    218             F1 += theory.F1*Rp_prob[k]*Re_prob[i] 
    219             F2 += theory.F2*Rp_prob[k]*Re_prob[i] 
    220             radius_eff += Rp_prob[k]*Re_prob[i]*ER_ellipsoid(Rpk,Rei) 
    221             total_weight += Rp_prob[k]*Re_prob[i] 
    222     F1 = F1/Normalization 
    223     F2 = F2/Normalization 
     213            weight = Rp_prob[k]*Re_prob[i] 
     214            total_weight += weight 
     215            total_volume += weight*volume 
     216            F1 += theory.F1*weight 
     217            F2 += theory.F2*weight 
     218            radius_eff += weight*ER_ellipsoid(Rpk,Rei) 
     219    F1 /= total_weight 
     220    F2 /= total_weight 
     221    average_volume = total_volume/total_weight 
    224222    if radius_effective is None: 
    225223        radius_effective = radius_eff/total_weight 
    226224    SQ = hardsphere_simple(q, radius_effective, volfraction) 
    227     SQ_EFF = 1 + F1**2/F2*(SQ - 1) 
    228     volume = ellipsoid_volume(radius_polar, radius_equatorial) 
    229225    if norm == 'sasfit': 
     226        beta = F1**2/F2 
     227        SQ_EFF = 1 + beta*(SQ - 1) 
    230228        IQD = F2 
    231229        IQSD = IQD*SQ 
    232230        IQBD = IQD*SQ_EFF 
    233231    elif norm == 'sasview': 
    234         IQD = F2*1e-4*volfraction 
     232        SQ_EFF = None 
     233        # Note: internally, sasview uses F2/total_volume because: 
     234        #   average_volume = total_volume/total_weight 
     235        #   F2/total_weight / average_volume 
     236        #     = F2/total_weight / total_volume/total_weight 
     237        #     = F2/total_volume 
     238        IQD = F2/average_volume*1e-4*volfraction 
    235239        IQSD = IQD*SQ 
    236         IQBD = IQD*SQ_EFF 
     240        IQBD = None 
    237241    elif norm == 'yun': 
    238         SQ_EFF = 1 + Normalization*F1**2/F2*(SQ - 1) 
    239         F2 = F2/volume 
    240         IQD = F2 
     242        #F1 /= average_volume 
     243        #F2 /= average_volume**2 
     244        F1 *= 1e-6  # Yun is using sld in 1/A^2, not 1e-6/A^2 
     245        F2 *= 1e-12 
     246        beta = F1**2/F2 
     247        SQ_EFF = 1 + beta*(SQ - 1) 
     248        IQD = F2/average_volume*1e8*volfraction 
    241249        IQSD = IQD*SQ 
    242250        IQBD = IQD*SQ_EFF 
     
    255263    elif radius_pd_type == 'schulz': 
    256264        radius_val, radius_prob = schulz_distribution(radius, radius_pd*radius, 0, inf) 
    257     Normalization=0 
     265    total_weight = total_volume = 0 
    258266    F1 = np.zeros_like(q) 
    259267    F2 = np.zeros_like(q) 
    260268    for k, rk in enumerate(radius_val): 
    261269        volume = 4./3.*pi*rk**3 
    262         if norm == 'sasfit': 
    263             Normalization += radius_prob[k] 
    264         elif norm == 'sasview' or norm == 'yun': 
    265             Normalization += radius_prob[k]*volume 
    266         F2k = ((sld-sld_solvent)*volume*sas_3j1x_x(q*rk))**2 
    267         F1k = (sld-sld_solvent)*volume*sas_3j1x_x(q*rk) 
    268         F2 += radius_prob[k]*F2k 
    269         F1 += radius_prob[k]*F1k 
    270  
    271     F2 = F2/Normalization 
    272     F1 = F1/Normalization 
     270        total_weight += radius_prob[k] 
     271        total_volume += radius_prob[k]*volume 
     272        form = (sld-sld_solvent)*volume*sas_3j1x_x(q*rk) 
     273        F2 += radius_prob[k]*form**2 
     274        F1 += radius_prob[k]*form 
     275    F1 /= total_weight 
     276    F2 /= total_weight 
     277    average_volume = total_volume/total_weight 
     278 
    273279    if radius_effective is None: 
    274280        radius_effective = radius 
    275281    SQ = hardsphere_simple(q, radius_effective, volfraction) 
    276     SQ_EFF = 1 + F1**2/F2*(SQ - 1) 
    277282    volume = 4./3.*pi*radius**3 
     283    average_volume = total_volume/total_weight 
    278284    if norm == 'sasfit': 
     285        beta = F1**2/F2 
     286        SQ_EFF = 1 + beta*(SQ - 1) 
    279287        IQD = F2 
    280288        IQSD = IQD*SQ 
    281289        IQBD = IQD*SQ_EFF 
    282290    elif norm == 'sasview': 
    283         IQD = F2*1e-4*volfraction 
     291        SQ_EFF = None 
     292        IQD = F2/average_volume*1e-4*volfraction 
    284293        IQSD = IQD*SQ 
    285         IQBD = IQD*SQ_EFF 
     294        IQBD = None 
    286295    elif norm == 'yun': 
    287         SQ_EFF = 1 + Normalization*F1**2/F2*(SQ - 1) 
    288         F2 = F2/volume 
    289         IQD = F2 
     296        # Note: yun uses gauss limits from R0/10 to R0 + 5 sigma steps sigma/100 
     297        # With pd = 0.1, that's 14 sigma, or 1400 points. 
     298        F1 *= 1e-6  # Yun is using sld in 1/A^2, not 1e-6/A^2 
     299        F2 *= 1e-12 
     300        beta = F1**2/F2 
     301        SQ_EFF = 1 + beta*(SQ - 1) 
     302        IQD = F2/average_volume*1e8*volfraction 
    290303        IQSD = IQD*SQ 
    291304        IQBD = IQD*SQ_EFF 
     
    364377        plt.legend(loc='lower left') 
    365378        plt.subplot(rows, 2, 2*row+2) 
    366         #plt.semilogx(Q, I2/I1 - 1, label="relative error") 
    367         plt.semilogx(Q, I1/I2 - 1, label="relative error") 
     379        plt.semilogx(Q, I2/I1 - 1, label="relative error") 
     380        #plt.semilogx(Q, I1/I2 - 1, label="relative error") 
    368381    plt.tight_layout() 
    369382    plt.suptitle(title) 
     
    412425    title = " ".join(("sasmodels", model, pd_type)) 
    413426    compare(title, target, actual) 
    414 COMPARISON[('sasview','ellipsoid','gaussian')] = lambda: compare_sasview_sphere(pd_type='gaussian') 
    415 COMPARISON[('sasview','ellipsoid','schulz')] = lambda: compare_sasview_sphere(pd_type='schulz') 
     427COMPARISON[('sasview','ellipsoid','gaussian')] = lambda: compare_sasview_ellipsoid(pd_type='gaussian') 
     428COMPARISON[('sasview','ellipsoid','schulz')] = lambda: compare_sasview_ellipsoid(pd_type='schulz') 
    416429 
    417430def compare_yun_ellipsoid_mono(): 
     
    425438        'radius_effective': 12.59921049894873, 
    426439    } 
    427     volume = ellipsoid_volume(pars['radius_polar'], pars['radius_equatorial']) 
    428440 
    429441    data = np.loadtxt(data_file('yun_ellipsoid.dat'),skiprows=2).T 
    430442    Q = data[0] 
    431443    F1 = data[1] 
    432     F2 = data[3] 
     444    P = data[3]*pars['volfraction'] 
    433445    S = data[5] 
    434446    Seff = data[6] 
    435     P = F2 
    436     I = P*S 
    437     Ibeta = P*Seff 
    438     P = I = Ibeta = None 
    439     target = Theory(Q=Q, F1=F1, F2=F2, P=P, S=S, I=I, Seff=Seff, Ibeta=Ibeta) 
     447    target = Theory(Q=Q, F1=F1, P=P, S=S, Seff=Seff) 
    440448    actual = ellipsoid_pe(Q, norm='yun', **pars) 
    441449    title = " ".join(("yun", "ellipsoid", "no pd")) 
     
    444452COMPARISON[('yun','ellipsoid','gaussian')] = compare_yun_ellipsoid_mono 
    445453COMPARISON[('yun','ellipsoid','schulz')] = compare_yun_ellipsoid_mono 
     454 
     455def compare_yun_sphere_gauss(): 
     456    pars = { 
     457        'radius': 20, 'radius_pd': 0.1, 'radius_pd_type': 'gaussian', 
     458        'sld': 6, 'sld_solvent': 0, 
     459        'volfraction': 0.1, 
     460    } 
     461 
     462    data = np.loadtxt(data_file('testPolydisperseGaussianSphere.dat'),skiprows=2).T 
     463    Q = data[0] 
     464    F1 = data[1] 
     465    P = data[3] 
     466    S = data[5] 
     467    Seff = data[6] 
     468    target = Theory(Q=Q, F1=F1, P=P, S=S, Seff=Seff) 
     469    actual = sphere_r(Q, norm='yun', **pars) 
     470    title = " ".join(("yun", "sphere", "10% dispersion 10% Vf")) 
     471    compare(title, target, actual) 
     472    data = np.loadtxt(data_file('testPolydisperseGaussianSphere2.dat'),skiprows=2).T 
     473    pars.update(radius_pd=0.15) 
     474    Q = data[0] 
     475    F1 = data[1] 
     476    P = data[3] 
     477    S = data[5] 
     478    Seff = data[6] 
     479    target = Theory(Q=Q, F1=F1, P=P, S=S, Seff=Seff) 
     480    actual = sphere_r(Q, norm='yun', **pars) 
     481    title = " ".join(("yun", "sphere", "15% dispersion 10% Vf")) 
     482    compare(title, target, actual) 
     483COMPARISON[('yun','sphere','gaussian')] = compare_yun_sphere_gauss 
     484 
    446485 
    447486def compare_sasfit_sphere_gauss(): 
     
    452491        'volfraction': 0.3, 
    453492    } 
    454     volume = 4./3.*pi*pars['radius']**3 
     493 
    455494    Q, IQ = load_sasfit(data_file('sasfit_sphere_IQD.txt')) 
    456495    Q, IQSD = load_sasfit(data_file('sasfit_sphere_IQSD.txt')) 
     
    474513        'volfraction': 0.3, 
    475514    } 
    476     volume = 4./3.*pi*pars['radius']**3 
    477515 
    478516    Q, IQ = load_sasfit(data_file('richard_test.txt')) 
     
    496534        'volfraction': 0.3, 'radius_effective': 13.1353356684, 
    497535    } 
    498     volume = ellipsoid_volume(pars['radius_polar'], pars['radius_equatorial']) 
     536 
    499537    Q, IQ = load_sasfit(data_file('richard_test4.txt')) 
    500538    Q, IQSD = load_sasfit(data_file('richard_test5.txt')) 
Note: See TracChangeset for help on using the changeset viewer.