static PyObject * unitRowVector(PyObject * self, PyObject * args) { PyArrayObject *vecIn, *vecOut; double *cIn, *cOut; int d; npy_intp n; if ( !PyArg_ParseTuple(args,"O", &vecIn)) return(NULL); if ( vecIn == NULL ) return(NULL); assert( PyArray_ISCONTIGUOUS(vecIn) ); assert( PyArray_ISALIGNED(vecIn) ); d = PyArray_NDIM(vecIn); assert(d == 1); n = PyArray_DIMS(vecIn)[0]; vecOut = (PyArrayObject*)PyArray_EMPTY(d,PyArray_DIMS(vecIn),NPY_DOUBLE,0); cIn = (double*)PyArray_DATA(vecIn); cOut = (double*)PyArray_DATA(vecOut); unitRowVector_cfunc(n,cIn,cOut); return((PyObject*)vecOut); }
/* * The only difference between this and the non-Array version * is that rMat_s is an array of matrices of length npts instead * of a single matrix. */ void gvecToDetectorXYArray_cfunc(long int npts, double * gVec_c, double * rMat_d, double * rMat_s, double * rMat_c, double * tVec_d, double * tVec_s, double * tVec_c, double * beamVec, double * result) { long int i; int j, k, l; double num; double nVec_l[3], bHat_l[3], P0_l[3], P3_l[3]; double rMat_sc[9]; /* Normalize the beam vector */ unitRowVector_cfunc(3,beamVec,bHat_l); for (i=0L; i<npts; i++) { /* Initialize the detector normal and frame origins */ num = 0.0; for (j=0; j<3; j++) { nVec_l[j] = 0.0; P0_l[j] = tVec_s[j]; for (k=0; k<3; k++) { nVec_l[j] += rMat_d[3*j+k]*Zl[k]; P0_l[j] += rMat_s[9*i + 3*j+k]*tVec_c[k]; } P3_l[j] = tVec_d[j]; num += nVec_l[j]*(P3_l[j]-P0_l[j]); } /* Compute the matrix product of rMat_s and rMat_c */ for (j=0; j<3; j++) { for (k=0; k<3; k++) { rMat_sc[3*j+k] = 0.0; for (l=0; l<3; l++) { rMat_sc[3*j+k] += rMat_s[9*i + 3*j+l]*rMat_c[3*l+k]; } } } gvecToDetectorXYOne_cfunc(&gVec_c[3*i], rMat_d, rMat_sc, tVec_d, bHat_l, nVec_l, num, P0_l, &result[2*i]); } }
void gvecToDetectorXYOne_cfunc(double * gVec_c, double * rMat_d, double * rMat_sc, double * tVec_d, double * bHat_l, double * nVec_l, double num, double * P0_l, double * result) { int j, k; double bDot, ztol, denom, u; double gHat_c[3], gVec_l[3], dVec_l[3], P2_l[3], P2_d[3]; double brMat[9]; ztol = epsf; /* Compute unit reciprocal lattice vector in crystal frame w/o translation */ unitRowVector_cfunc(3,gVec_c,gHat_c); /* Compute unit reciprocal lattice vector in lab frame and dot with beam vector */ bDot = 0.0; for (j=0; j<3; j++) { gVec_l[j] = 0.0; for (k=0; k<3; k++) gVec_l[j] += rMat_sc[3*j+k]*gHat_c[k]; bDot -= bHat_l[j]*gVec_l[j]; } if ( bDot >= ztol && bDot <= 1.0-ztol ) { /* If we are here diffraction is possible so increment the number of admissable vectors */ makeBinaryRotMat_cfunc(gVec_l,brMat); denom = 0.0; for (j=0; j<3; j++) { dVec_l[j] = 0.0; for (k=0; k<3; k++) dVec_l[j] -= brMat[3*j+k]*bHat_l[k]; denom += nVec_l[j]*dVec_l[j]; } if ( denom < -ztol ) { u = num/denom; for (j=0; j<3; j++) P2_l[j] = P0_l[j]+u*dVec_l[j]; for (j=0; j<2; j++) { P2_d[j] = 0.0; for (k=0; k<3; k++) P2_d[j] += rMat_d[3*k+j]*(P2_l[k]-tVec_d[k]); result[j] = P2_d[j]; } } else { result[0] = NAN; result[1] = NAN; } } else { result[0] = NAN; result[1] = NAN; } }