static PyObject * makeOscillRotMat(PyObject * self, PyObject * args) { PyArrayObject *oscillAngles, *rMat; int doa; npy_intp no, dims[2]; double *oPtr, *rPtr; /* Parse arguments */ if ( !PyArg_ParseTuple(args,"O", &oscillAngles)) return(NULL); if ( oscillAngles == NULL ) return(NULL); /* Verify shape of input arrays */ doa = PyArray_NDIM(oscillAngles); assert( doa == 1 ); /* Verify dimensions of input arrays */ no = PyArray_DIMS(oscillAngles)[0]; assert( no == 2 ); /* Allocate the result matrix with appropriate dimensions and type */ dims[0] = 3; dims[1] = 3; rMat = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0); /* Grab pointers to the various data arrays */ oPtr = (double*)PyArray_DATA(oscillAngles); rPtr = (double*)PyArray_DATA(rMat); /* Call the actual function */ makeOscillRotMat_cfunc(oPtr,rPtr); return((PyObject*)rMat); }
void anglesToGvec_cfunc(long int nvecs, double * angs, double * bHat_l, double * eHat_l, double chi, double * rMat_c, double * gVec_c) { /* * takes an angle spec (2*theta, eta, omega) for nvecs g-vectors and * returns the unit g-vector components in the crystal frame * * For unit g-vector in the lab frame, spec rMat_c = Identity and * overwrite the omega values with zeros */ int i, j, k, l; double rMat_e[9], rMat_s[9], rMat_ctst[9]; double gVec_e[3], gVec_l[3], gVec_c_tmp[3]; /* Need eta frame cob matrix (could omit for standard setting) */ makeEtaFrameRotMat_cfunc(bHat_l, eHat_l, rMat_e); /* make vector array */ for (i=0; i<nvecs; i++) { /* components in BEAM frame */ gVec_e[0] = cos(0.5*angs[3*i]) * cos(angs[3*i+1]); gVec_e[1] = cos(0.5*angs[3*i]) * sin(angs[3*i+1]); gVec_e[2] = sin(0.5*angs[3*i]); /* take from beam frame to lab frame */ for (j=0; j<3; j++) { gVec_l[j] = 0.0; for (k=0; k<3; k++) { gVec_l[j] += rMat_e[3*j+k]*gVec_e[k]; } } /* need pointwise rMat_s according to omega */ makeOscillRotMat_cfunc(chi, angs[3*i+2], rMat_s); /* Compute dot(rMat_c.T, rMat_s.T) and hit against gVec_l */ for (j=0; j<3; j++) { for (k=0; k<3; k++) { rMat_ctst[3*j+k] = 0.0; for (l=0; l<3; l++) { rMat_ctst[3*j+k] += rMat_c[3*l+j]*rMat_s[3*k+l]; } } gVec_c_tmp[j] = 0.0; for (k=0; k<3; k++) { gVec_c_tmp[j] += rMat_ctst[3*j+k]*gVec_l[k]; } gVec_c[3*i+j] = gVec_c_tmp[j]; } } }
static PyObject * makeOscillRotMatArray(PyObject * self, PyObject * args) { PyObject *chiObj; double chi; PyArrayObject *omeArray, *rMat; int doa; npy_intp i, no, dims[3]; double *oPtr, *rPtr; /* Parse arguments */ if ( !PyArg_ParseTuple(args,"OO", &chiObj, &omeArray)) return(NULL); if ( chiObj == NULL ) return(NULL); if ( omeArray == NULL ) return(NULL); /* Get chi */ chi = PyFloat_AsDouble(chiObj); if (chi == -1 && PyErr_Occurred()) return(NULL); /* Verify shape of input arrays */ doa = PyArray_NDIM(omeArray); assert( doa == 1 ); /* Verify dimensions of input arrays */ no = PyArray_DIMS(omeArray)[0]; /* Allocate the result matrix with appropriate dimensions and type */ dims[0] = no; dims[1] = 3; dims[2] = 3; rMat = (PyArrayObject*)PyArray_EMPTY(3,dims,NPY_DOUBLE,0); /* Grab pointers to the various data arrays */ oPtr = (double*)PyArray_DATA(omeArray); rPtr = (double*)PyArray_DATA(rMat); /* Call the actual function repeatedly */ for (i = 0; i < no; ++i) { makeOscillRotMat_cfunc(chi, oPtr[i], rPtr + i*9); } return((PyObject*)rMat); }
void oscillAnglesOfHKLs_cfunc(long int npts, double * hkls, double chi, double * rMat_c, double * bMat, double wavelength, double * vInv_s, double * beamVec, double * etaVec, double * oangs0, double * oangs1) { long int i; int j, k; bool crc = false; double gVec_e[3], gHat_c[3], gHat_s[3], bHat_l[3], eHat_l[3], oVec[2]; double tVec0[3], tmpVec[3]; double rMat_e[9], rMat_s[9]; double a, b, c, sintht, cchi, schi; double abMag, phaseAng, rhs, rhsAng; double nrm0; /* Normalize the beam vector */ nrm0 = 0.0; for (j=0; j<3; j++) { nrm0 += beamVec[j]*beamVec[j]; } nrm0 = sqrt(nrm0); if ( nrm0 > epsf ) { for (j=0; j<3; j++) bHat_l[j] = beamVec[j]/nrm0; } else { for (j=0; j<3; j++) bHat_l[j] = beamVec[j]; } /* Normalize the eta vector */ nrm0 = 0.0; for (j=0; j<3; j++) { nrm0 += etaVec[j]*etaVec[j]; } nrm0 = sqrt(nrm0); if ( nrm0 > epsf ) { for (j=0; j<3; j++) eHat_l[j] = etaVec[j]/nrm0; } else { for (j=0; j<3; j++) eHat_l[j] = etaVec[j]; } /* Check for consistent reference coordiantes */ nrm0 = 0.0; for (j=0; j<3; j++) { nrm0 += bHat_l[j]*eHat_l[j]; } if ( fabs(nrm0) < 1.0-sqrt_epsf ) crc = true; /* Compute the sine and cosine of the oscillation axis tilt */ cchi = cos(chi); schi = sin(chi); for (i=0; i<npts; i++) { /* Compute gVec_c */ for (j=0; j<3; j++) { gHat_c[j] = 0.0; for (k=0; k<3; k++) { gHat_c[j] += bMat[3*j+k]*hkls[3L*i+k]; } } /* Apply rMat_c to get gVec_s */ for (j=0; j<3; j++) { gHat_s[j] = 0.0; for (k=0; k<3; k++) { gHat_s[j] += rMat_c[3*j+k]*gHat_c[k]; } } /* Apply vInv_s to gVec_s and store in tmpVec*/ tmpVec[0] = vInv_s[0]*gHat_s[0] + (vInv_s[5]*gHat_s[1] + vInv_s[4]*gHat_s[2])/sqrt(2.); tmpVec[1] = vInv_s[1]*gHat_s[1] + (vInv_s[5]*gHat_s[0] + vInv_s[3]*gHat_s[2])/sqrt(2.); tmpVec[2] = vInv_s[2]*gHat_s[2] + (vInv_s[4]*gHat_s[0] + vInv_s[3]*gHat_s[1])/sqrt(2.); /* Apply rMat_c.T to get stretched gVec_c and store norm in nrm0*/ nrm0 = 0.0; for (j=0; j<3; j++) { gHat_c[j] = 0.0; for (k=0; k<3; k++) { gHat_c[j] += rMat_c[j+3*k]*tmpVec[k]; } nrm0 += gHat_c[j]*gHat_c[j]; } nrm0 = sqrt(nrm0); /* Normalize both gHat_c and gHat_s */ if ( nrm0 > epsf ) { for (j=0; j<3; j++) { gHat_c[j] /= nrm0; gHat_s[j] = tmpVec[j]/nrm0; } } /* Compute the sine of the Bragg angle */ sintht = 0.5*wavelength*nrm0; /* Compute the coefficients of the harmonic equation */ a = gHat_s[2]*bHat_l[0] + schi*gHat_s[0]*bHat_l[1] - cchi*gHat_s[0]*bHat_l[2]; b = gHat_s[0]*bHat_l[0] - schi*gHat_s[2]*bHat_l[1] + cchi*gHat_s[2]*bHat_l[2]; c = - sintht - cchi*gHat_s[1]*bHat_l[1] - schi*gHat_s[1]*bHat_l[2]; /* Form solution */ abMag = sqrt(a*a + b*b); assert( abMag > 0.0 ); phaseAng = atan2(b,a); rhs = c/abMag; if ( fabs(rhs) > 1.0 ) { for (j=0; j<3; j++) oangs0[3L*i+j] = NAN; for (j=0; j<3; j++) oangs1[3L*i+j] = NAN; continue; } rhsAng = asin(rhs); /* Write ome angles */ oangs0[3L*i+2] = rhsAng - phaseAng; oangs1[3L*i+2] = M_PI - rhsAng - phaseAng; if ( crc ) { makeEtaFrameRotMat_cfunc(bHat_l,eHat_l,rMat_e); oVec[0] = chi; oVec[1] = oangs0[3L*i+2]; makeOscillRotMat_cfunc(oVec[0], oVec[1], rMat_s); for (j=0; j<3; j++) { tVec0[j] = 0.0; for (k=0; k<3; k++) { tVec0[j] += rMat_s[3*j+k]*gHat_s[k]; } } for (j=0; j<2; j++) { gVec_e[j] = 0.0; for (k=0; k<3; k++) { gVec_e[j] += rMat_e[3*k+j]*tVec0[k]; } } oangs0[3L*i+1] = atan2(gVec_e[1],gVec_e[0]); oVec[1] = oangs1[3L*i+2]; makeOscillRotMat_cfunc(oVec[0], oVec[1], rMat_s); for (j=0; j<3; j++) { tVec0[j] = 0.0; for (k=0; k<3; k++) { tVec0[j] += rMat_s[3*j+k]*gHat_s[k]; } } for (j=0; j<2; j++) { gVec_e[j] = 0.0; for (k=0; k<3; k++) { gVec_e[j] += rMat_e[3*k+j]*tVec0[k]; } } oangs1[3L*i+1] = atan2(gVec_e[1],gVec_e[0]); oangs0[3L*i+0] = 2.0*asin(sintht); oangs1[3L*i+0] = oangs0[3L*i+0]; } } }