Changeset 87a6591 in sasmodels


Ignore:
Timestamp:
Oct 29, 2017 9:33:00 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:
5b5ea20
Parents:
dd4d95d
git-author:
Paul Kienzle <pkienzle@…> (10/29/17 21:32:22)
git-committer:
Paul Kienzle <pkienzle@…> (10/29/17 21:33:00)
Message:

explore different map projections for jitter

File:
1 edited

Legend:

Unmodified
Added
Removed
  • explore/jitter.py

    r0db85af r87a6591  
    1515import numpy as np 
    1616from numpy import pi, cos, sin, sqrt, exp, degrees, radians 
    17  
    18 SCALED_PHI = True 
    1917 
    2018def draw_beam(ax, view=(0, 0)): 
     
    179177        raise ValueError("expected dist to be 'gaussian' or 'rectangle'") 
    180178 
    181     if SCALED_PHI: 
    182         scale_phi = lambda dtheta, dphi: ( 
    183             dphi/abs(cos(radians(dtheta))) if dtheta != 90 
    184             else 0 if dphi == 0 
    185             else 4*pi) 
    186         w = np.outer(weights, weights) 
     179    #PROJECTION = 'stretched_phi' 
     180    PROJECTION = 'azimuthal_equidistance' 
     181    #PROJECTION = 'azimuthal_equal_area' 
     182    if PROJECTION == 'stretced_phi': 
     183        def rotate(theta_i, phi_j): 
     184            if theta_i != 90: 
     185                phi_j /= cos(radians(theta_i)) 
     186            return Rx(phi_j)*Ry(theta_i) 
     187        def weight(theta_i, phi_j, wi, wj): 
     188            if theta_i != 90: 
     189                phi_j /= cos(radians(theta_i)) 
     190            return wi*wj if abs(phi_j) < 180 else 0 
     191    elif PROJECTION == 'azimuthal_equidistance': 
     192        # https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection 
     193        def rotate(theta_i, phi_j): 
     194            latitude = sqrt(theta_i**2 + phi_j**2) 
     195            longitude = degrees(np.arctan2(phi_j, theta_i)) 
     196            #print("(%+7.2f, %+7.2f) => (%+7.2f, %+7.2f)"%(theta_i, phi_j, latitude, longitude)) 
     197            return Rz(longitude)*Ry(latitude) 
     198        def weight(theta_i, phi_j, wi, wj): 
     199            latitude = sqrt(theta_i**2 + phi_j**2) 
     200            w = wi*wj if latitude < 180 else 0 
     201            return w 
     202    elif PROJECTION == 'azimuthal_equal_area': 
     203        # https://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection 
     204        def rotate(theta_i, phi_j): 
     205            R = min(1, sqrt(theta_i**2 + phi_j**2)/180) 
     206            latitude = 180-degrees(2*np.arccos(R)) 
     207            longitude = degrees(np.arctan2(phi_j, theta_i)) 
     208            #print("(%+7.2f, %+7.2f) => (%+7.2f, %+7.2f)"%(theta_i, phi_j, latitude, longitude)) 
     209            return Rz(longitude)*Ry(latitude) 
     210        def weight(theta_i, phi_j, wi, wj): 
     211            R = sqrt(theta_i**2 + phi_j**2) 
     212            return wi*wj if R <= 180 else 0 
     213            #return wi*wj if latitude <= 180 else 0 
     214    elif SCALED_PHI == 10:  # random thrashing 
     215        def rotate(theta_i, phi_j): 
     216            theta_i, phi_j = 2*theta_i/abs(cos(radians(phi_j))), 2*phi_j/cos(radians(theta_i)) 
     217            return Rx(phi_j)*Ry(theta_i) 
     218        def weight(theta_i, phi_j, wi, wj): 
     219            theta_i, phi_j = 2*theta_i/abs(cos(radians(phi_j))), 2*phi_j/cos(radians(theta_i)) 
     220            return wi*wj if abs(phi_j) < 180 else 0 
    187221    else: 
    188         scale_phi = lambda dtheta, dphe: dphi 
    189         w = np.outer(weights*cos(radians(dtheta*t)), weights) 
     222        def rotate(theta_i, phi_j): 
     223            return Rx(phi_j)*Ry(theta_i) 
     224        def weight(theta_i, phi_j, wi, wj): 
     225            return wi*wj*cos(radians(theta_i)) 
    190226 
    191227    # mesh in theta, phi formed by rotating z 
    192228    z = np.matrix([[0], [0], [radius]]) 
    193     points = np.hstack([Rx(scale_phi(theta_i, phi_j))*Ry(theta_i)*z 
     229    points = np.hstack([rotate(theta_i, phi_j)*z 
    194230                        for theta_i in dtheta*t 
    195231                        for phi_j in dphi*t]) 
    196232    # select just the active points (i.e., those with phi < 180 
    197     active = np.array([abs(scale_phi(theta_i, phi_j)) < 180 
    198                        for theta_i in dtheta*t 
    199                        for phi_j in dphi*t]) 
    200     points = points[:, active] 
    201     w = w.flatten()[active] 
     233    w = np.array([weight(theta_i, phi_j, wi, wj) 
     234                  for wi, theta_i in zip(weights, dtheta*t) 
     235                  for wj, phi_j in zip(weights, dphi*t)]) 
     236    points = points[:, w>0] 
     237    w = w[w>0] 
     238 
     239    if 0: # Kent distribution 
     240        points = np.hstack([Rx(phi_j)*Ry(theta_i)*z for theta_i in 30*t for phi_j in 60*t]) 
     241        xp, yp, zp = [np.array(v).flatten() for v in points] 
     242        kappa = max(1e6, radians(dtheta)/(2*pi)) 
     243        beta = 1/max(1e-6, radians(dphi)/(2*pi))/kappa 
     244        w = exp(kappa*zp) #+ beta*(xp**2 + yp**2) 
     245        print(kappa, dtheta, radians(dtheta), min(w), max(w), sum(w)) 
     246        #w /= abs(cos(radians( 
     247        #w /= sum(w) 
    202248 
    203249    # rotate relative to beam 
     
    205251 
    206252    x, y, z = [np.array(v).flatten() for v in points] 
     253    #plt.figure(2); plt.clf(); plt.hist(z, bins=np.linspace(-1, 1, 51)) 
    207254    ax.scatter(x, y, z, c=w, marker='o', vmin=0., vmax=1.) 
    208255 
Note: See TracChangeset for help on using the changeset viewer.