Esempio n. 1
0
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);
}
Esempio n. 2
0
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];
    }
  }
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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];
    }
  }
}