Changeset 8698a0d in sasmodels for sasmodels/kernel_iq.c


Ignore:
Timestamp:
Oct 17, 2017 11:53:01 PM (7 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:
32f87a5
Parents:
becded3
git-author:
Paul Kienzle <pkienzle@…> (10/17/17 18:23:09)
git-committer:
Paul Kienzle <pkienzle@…> (10/17/17 23:53:01)
Message:

revise api for oriented shapes, allowing jitter in the frame of the sample

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernel_iq.c

    rd4c33d6 r8698a0d  
    2525    int32_t num_weights;        // total length of the weights vector 
    2626    int32_t num_active;         // number of non-trivial pd loops 
    27     int32_t theta_par;          // id of spherical correction variable (not used) 
     27    int32_t theta_par;          // id of first orientation variable 
    2828} ProblemDetails; 
    2929 
     
    6969    return sld + perp*p; 
    7070} 
    71  
    72 #endif // MAGNETIC 
     71//#endif // MAGNETIC 
     72 
     73// TODO: way too hackish 
     74// For the 1D kernel, CALL_IQ_[A,AC,ABC] and MAGNETIC are not defined 
     75// so view_direct *IS NOT* included 
     76// For the 2D kernel, CALL_IQ_[A,AC,ABC] is defined but MAGNETIC is not 
     77// so view_direct *IS* included 
     78// For the magnetic kernel, CALL_IQ_[A,AC,ABC] is defined, but so is MAGNETIC 
     79// so view_direct *IS NOT* included 
     80#else // !MAGNETIC 
     81 
     82// ===== Implement jitter in orientation ===== 
     83// To change the definition of the angles, run explore/angles.py, which 
     84// uses sympy to generate the equations. 
     85 
     86#if defined(CALL_IQ_AC) // oriented symmetric 
     87static double 
     88view_direct(double qx, double qy, 
     89             double theta, double phi, 
     90             ParameterTable table) 
     91{ 
     92    double sin_theta, cos_theta; 
     93    double sin_phi, cos_phi; 
     94 
     95    // reverse view 
     96    SINCOS(theta*M_PI_180, sin_theta, cos_theta); 
     97    SINCOS(phi*M_PI_180, sin_phi, cos_phi); 
     98    const double qa = qx*cos_phi*cos_theta + qy*sin_phi*cos_theta; 
     99    const double qb = -qx*sin_phi + qy*cos_phi; 
     100    const double qc = qx*sin_theta*cos_phi + qy*sin_phi*sin_theta; 
     101 
     102    // reverse jitter after view 
     103    SINCOS(table.theta*M_PI_180, sin_theta, cos_theta); 
     104    SINCOS(table.phi*M_PI_180, sin_phi, cos_phi); 
     105    const double dqc = qa*sin_theta - qb*sin_phi*cos_theta + qc*cos_phi*cos_theta; 
     106 
     107    // Indirect calculation of qab, from qab^2 = |q|^2 - qc^2 
     108    const double dqa = sqrt(-dqc*dqc + qx*qx + qy*qy); 
     109 
     110    return CALL_IQ_AC(dqa, dqc, table); 
     111} 
     112 
     113#elif defined(CALL_IQ_ABC) // oriented asymmetric 
     114 
     115static double 
     116view_direct(double qx, double qy, 
     117             double theta, double phi, double psi, 
     118             ParameterTable table) 
     119{ 
     120    double sin_theta, cos_theta; 
     121    double sin_phi, cos_phi; 
     122    double sin_psi, cos_psi; 
     123 
     124    // reverse view 
     125    SINCOS(theta*M_PI_180, sin_theta, cos_theta); 
     126    SINCOS(phi*M_PI_180, sin_phi, cos_phi); 
     127    SINCOS(psi*M_PI_180, sin_psi, cos_psi); 
     128    const double qa = qx*(sin_phi*sin_psi + cos_phi*cos_psi*cos_theta) + qy*(sin_phi*cos_psi*cos_theta - sin_psi*cos_phi); 
     129    const double qb = qx*(-sin_phi*cos_psi + sin_psi*cos_phi*cos_theta) + qy*(sin_phi*sin_psi*cos_theta + cos_phi*cos_psi); 
     130    const double qc = qx*sin_theta*cos_phi + qy*sin_phi*sin_theta; 
     131 
     132    // reverse jitter after view 
     133    SINCOS(table.theta*M_PI_180, sin_theta, cos_theta); 
     134    SINCOS(table.phi*M_PI_180, sin_phi, cos_phi); 
     135    SINCOS(table.psi*M_PI_180, sin_psi, cos_psi); 
     136    const double dqa = qa*cos_psi*cos_theta + qb*(sin_phi*sin_theta*cos_psi - sin_psi*cos_phi) + qc*(-sin_phi*sin_psi - sin_theta*cos_phi*cos_psi); 
     137    const double dqb = qa*sin_psi*cos_theta + qb*(sin_phi*sin_psi*sin_theta + cos_phi*cos_psi) + qc*(sin_phi*cos_psi - sin_psi*sin_theta*cos_phi); 
     138    const double dqc = qa*sin_theta - qb*sin_phi*cos_theta + qc*cos_phi*cos_theta; 
     139 
     140    return CALL_IQ_ABC(dqa, dqb, dqc, table); 
     141} 
     142/* TODO: use precalculated jitter for faster 2D calcs on DLL. 
     143static void 
     144view_precalc( 
     145    double theta, double phi, double psi, 
     146    ParameterTable table, 
     147    double *R11, double *R12, double *R21, 
     148    double *R22, double *R31, double *R32) 
     149{ 
     150    double sin_theta, cos_theta; 
     151    double sin_phi, cos_phi; 
     152    double sin_psi, cos_psi; 
     153 
     154    // reverse view matrix 
     155    SINCOS(theta*M_PI_180, sin_theta, cos_theta); 
     156    SINCOS(phi*M_PI_180, sin_phi, cos_phi); 
     157    SINCOS(psi*M_PI_180, sin_psi, cos_psi); 
     158    const double V11 = sin_phi*sin_psi + cos_phi*cos_psi*cos_theta; 
     159    const double V12 = sin_phi*cos_psi*cos_theta - sin_psi*cos_phi; 
     160    const double V21 = -sin_phi*cos_psi + sin_psi*cos_phi*cos_theta; 
     161    const double V22 = sin_phi*sin_psi*cos_theta + cos_phi*cos_psi; 
     162    const double V31 = sin_theta*cos_phi; 
     163    const double V32 = sin_phi*sin_theta; 
     164 
     165    // reverse jitter matrix 
     166    SINCOS(table.theta*M_PI_180, sin_theta, cos_theta); 
     167    SINCOS(table.phi*M_PI_180, sin_phi, cos_phi); 
     168    SINCOS(table.psi*M_PI_180, sin_psi, cos_psi); 
     169    const double J11 = cos_psi*cos_theta; 
     170    const double J12 = sin_phi*sin_theta*cos_psi - sin_psi*cos_phi; 
     171    const double J13 = -sin_phi*sin_psi - sin_theta*cos_phi*cos_psi; 
     172    const double J21 = sin_psi*cos_theta; 
     173    const double J22 = sin_phi*sin_psi*sin_theta + cos_phi*cos_psi; 
     174    const double J23 = sin_phi*cos_psi - sin_psi*sin_theta*cos_phi; 
     175    const double J31 = sin_theta; 
     176    const double J32 = -sin_phi*cos_theta; 
     177    const double J33 = cos_phi*cos_theta; 
     178 
     179    // reverse matrix 
     180    *R11 = J11*V11 + J12*V21 + J13*V31; 
     181    *R12 = J11*V12 + J12*V22 + J13*V32; 
     182    *R21 = J21*V11 + J22*V21 + J23*V31; 
     183    *R22 = J21*V12 + J22*V22 + J23*V32; 
     184    *R31 = J31*V11 + J32*V21 + J33*V31; 
     185    *R32 = J31*V12 + J32*V22 + J33*V32; 
     186} 
     187 
     188static double 
     189view_apply(double qx, double qy, 
     190    double R11, double R12, double R21, double R22, double R31, double R32, 
     191    ParameterTable table) 
     192{ 
     193    const double dqa = R11*qx + R12*qy; 
     194    const double dqb = R21*qx + R22*qy; 
     195    const double dqc = R31*qx + R32*qy; 
     196 
     197    CALL_IQ_ABC(dqa, dqb, dqc, table); 
     198} 
     199*/ 
     200#endif 
     201 
     202#endif // !MAGNETIC 
    73203 
    74204kernel 
     
    105235  SINCOS(-values[NUM_PARS+4]*M_PI_180, sin_mspin, cos_mspin); 
    106236#endif // MAGNETIC 
     237 
     238#if defined(CALL_IQ_AC) // oriented symmetric 
     239  const double theta = values[details->theta_par+2]; 
     240  const double phi = values[details->theta_par+3]; 
     241#elif defined(CALL_IQ_ABC) // oriented asymmetric 
     242  const double theta = values[details->theta_par+2]; 
     243  const double phi = values[details->theta_par+3]; 
     244  const double psi = values[details->theta_par+4]; 
     245#endif 
    107246 
    108247  // Fill in the initial variables 
     
    275414                  } 
    276415                  #endif 
    277                   scattering += CALL_IQ(q, q_index, local_values.table); 
     416#  if defined(CALL_IQ_A) // unoriented 
     417                  scattering += CALL_IQ_A(sqrt(qsq), local_values.table); 
     418#  elif defined(CALL_IQ_AC) // oriented symmetric 
     419                  scattering += view_direct(qx, qy, theta, phi, local_values.table); 
     420#  elif defined(CALL_IQ_ABC) // oriented asymmetric 
     421                  scattering += view_direct(qx, qy, theta, phi, psi, local_values.table); 
     422#  endif 
    278423                } 
    279424              } 
    280425            } 
    281426          } 
    282 #else  // !MAGNETIC 
    283           const double scattering = CALL_IQ(q, q_index, local_values.table); 
     427#elif defined(CALL_IQ) // 1d, not MAGNETIC 
     428          const double scattering = CALL_IQ(q[q_index], local_values.table); 
     429#else  // 2d data, not magnetic 
     430          const double qx = q[2*q_index]; 
     431          const double qy = q[2*q_index+1]; 
     432#  if defined(CALL_IQ_A) // unoriented 
     433          const double scattering = CALL_IQ_A(sqrt(qx*qx+qy*qy), local_values.table); 
     434#  elif defined(CALL_IQ_AC) // oriented symmetric 
     435          const double scattering = view_direct(qx, qy, theta, phi, local_values.table); 
     436#  elif defined(CALL_IQ_ABC) // oriented asymmetric 
     437          const double scattering = view_direct(qx, qy, theta, phi, psi, local_values.table); 
     438#  endif 
    284439#endif // !MAGNETIC 
    285440//printf("q_index:%d %g %g %g %g\n",q_index, scattering, weight, spherical_correction, weight0); 
Note: See TracChangeset for help on using the changeset viewer.