def calcEtaMin(tth, psi):
    th = tth / 2
    #	if psi <= th:
    #		etaMin = 0
    #	else:
    #		etaMin = asind((sind(psi)**2 - sind(th)**2)**0.5 / (bc.cosd(th) * sind(psi)))
    if psi == 0:
        return 0
    else:
        return bc.asind((max(0,
                             bc.sind(psi)**2 - bc.sind(th)**2))**0.5 /
                        (bc.cosd(th) * bc.sind(psi)))
def universalPlotAnalysis(data,
                          maxPsi=None,
                          minDistPsiStar=0.15,
                          minValPsiNormal=0.08,
                          minValPsiShear=0.8):
    # extract needed data
    a0Val = bf.getDictValOrDef(data, 'a0Val')
    psiUni = data['psiUni']
    sin2psiUni = data['sin2psiUni']
    sinpsi2Uni = data['sinpsi2Uni']
    psiVals = data['psiVals']
    phiVals = data['phiVals']
    dVals = data['dVals']
    dErrVals = data['dErrVals']
    tauVals = data['tauVals']
    hklVal = data['hklVal']
    s1Val = data['s1Val']
    hs2Val = data['hs2Val']
    phi4 = data['phi4']
    dValsValid = (dVals > 0) & (np.isnan(dVals) == False)
    tauValsValid = (tauVals >= 0) & (tauVals < 1e6)
    # define needed variables
    sinpsi2Star = -2 * s1Val / hs2Val
    psiStar = bc.asind(sinpsi2Star**0.5)
    valsAll = np.zeros((len(psiUni), 3))
    fplus = np.zeros((len(psiUni), 3))
    fminus = np.zeros((len(psiUni), 3))
    f13 = np.zeros((len(psiUni), 3))
    f23 = np.zeros((len(psiUni), 3))
    stresses = np.zeros((len(psiUni), 4))
    errVals = np.zeros((len(psiUni), 4))
    tauRes = np.zeros(len(psiUni))
    resData = dict()
    validCounter = 0
    for i in range(len(psiUni)):
        if phi4:
            cond0 = (psiVals == psiUni[i]) & (phiVals == 0) & dValsValid
            cond90 = (psiVals == psiUni[i]) & (phiVals == 90) & dValsValid
            cond180 = (psiVals == psiUni[i]) & (phiVals == 180) & dValsValid
            cond270 = (psiVals == psiUni[i]) & (phiVals == 270) & dValsValid
        else:
            cond0 = (psiVals == psiUni[i]) & (phiVals == 0) & dValsValid
            cond90 = (psiVals == psiUni[i]) & (phiVals == 90) & dValsValid
            cond180 = (psiVals == -psiUni[i]) & (phiVals == 0) & dValsValid
            cond270 = (psiVals == -psiUni[i]) & (phiVals == 90) & dValsValid
        val0 = np.concatenate((dVals[cond0], dVals[cond0] - dErrVals[cond0],
                               dVals[cond0] + dErrVals[cond0]))
        val90 = np.concatenate(
            (dVals[cond90], dVals[cond90] - dErrVals[cond90],
             dVals[cond90] + dErrVals[cond90]))
        val180 = np.concatenate(
            (dVals[cond180], dVals[cond180] - dErrVals[cond180],
             dVals[cond180] + dErrVals[cond180]))
        val270 = np.concatenate(
            (dVals[cond270], dVals[cond270] - dErrVals[cond270],
             dVals[cond270] + dErrVals[cond270]))
        if len(val0) > 0 and len(val90) > 0 and len(val180) > 0 and len(
                val270) > 0:
            fplus[i, :] = val0 + val90 + val180 + val270
            fminus[i, :] = (val0 + val180) - (val90 + val270)
            f13[i, :] = val0 - val180
            f23[i, :] = val90 - val270
            valsAll[i, :] = 0.25 * fplus[i, :]
            tauRes[i] = np.mean(tauVals[(psiVals == psiUni[i]) & tauValsValid])
            validCounter += 1
    # perform linear regression for all phi values to get dstar
    used = valsAll[:, 0] != 0
    if len(valsAll[used, 0]) > 1:
        if maxPsi is not None:
            usedReg = (sinpsi2Uni <= bc.sind(maxPsi)**2) & used
        else:
            usedReg = used
        [m, b, CoD, yD, err, mErr,
         bErr] = dm.linRegWeighted(sinpsi2Uni[usedReg], valsAll[usedReg, 0],
                                   1 / valsAll[usedReg, 1])
        dStarVal = m * sinpsi2Star + b
        # calculate fplus
        denom = hs2Val * sinpsi2Uni[used] + 2 * s1Val
        fplus[used, 0] = (0.25 * fplus[used, 0] / dStarVal - 1) / denom
        fplus[used, 1] = (0.25 * fplus[used, 1] / dStarVal - 1) / denom
        fplus[used, 2] = (0.25 * fplus[used, 2] / dStarVal - 1) / denom
        # indicate or correct invalid values
        if minDistPsiStar is not None:
            invalidVals = used & (np.abs(sinpsi2Uni - sinpsi2Star) <=
                                  minDistPsiStar)  # around psiStar
            fplus[invalidVals, 0] = np.NAN
            fplus[invalidVals, 1] = np.NAN
            fplus[invalidVals, 2] = np.NAN
        # fplus[used, 0] = (0.25 * fplus[used, 0] / dStarVal - 1) / (np.sign(denom) * np.array(
        # 	[np.max((np.abs(i), 5e-7)) for i in denom]))  # constrained denominator
        # fplus[used, 1] = (0.25 * fplus[used, 1] / dStarVal - 1) / (np.sign(denom) * np.array(
        # 	[np.max((np.abs(i), 5e-7)) for i in denom]))  # constrained denominator
        # fplus[used, 2] = (0.25 * fplus[used, 2] / dStarVal - 1) / (np.sign(denom) * np.array(
        # 	[np.max((np.abs(i), 5e-7)) for i in denom]))  # constrained denominator
        # calculate fminus
        fminus[used, 0] = 0.25 * (fminus[used, 0] /
                                  dStarVal) / (hs2Val * sinpsi2Uni[used])
        fminus[used, 1] = 0.25 * (fminus[used, 1] /
                                  dStarVal) / (hs2Val * sinpsi2Uni[used])
        fminus[used, 2] = 0.25 * (fminus[used, 2] /
                                  dStarVal) / (hs2Val * sinpsi2Uni[used])
        # indicate invalid values
        if minValPsiNormal is not None:
            invalidVals = used & (sinpsi2Uni <= minValPsiNormal
                                  )  # small psi values
            fminus[invalidVals, 0] = np.NAN
            fminus[invalidVals, 1] = np.NAN
            fminus[invalidVals, 2] = np.NAN
        # calculate f13 and f23
        f13[used,
            0] = 0.5 * (f13[used, 0] / dStarVal) / (hs2Val * sin2psiUni[used])
        f13[used,
            1] = 0.5 * (f13[used, 1] / dStarVal) / (hs2Val * sin2psiUni[used])
        f13[used,
            2] = 0.5 * (f13[used, 2] / dStarVal) / (hs2Val * sin2psiUni[used])
        f23[used,
            0] = 0.5 * (f23[used, 0] / dStarVal) / (hs2Val * sin2psiUni[used])
        f23[used,
            1] = 0.5 * (f23[used, 1] / dStarVal) / (hs2Val * sin2psiUni[used])
        f23[used,
            2] = 0.5 * (f23[used, 2] / dStarVal) / (hs2Val * sin2psiUni[used])
        # indicate invalid values
        if minValPsiShear is not None:
            invalidVals = used & (sin2psiUni <= minValPsiShear
                                  )  # small and high psi values
            f13[invalidVals, 0] = np.NAN
            f13[invalidVals, 1] = np.NAN
            f13[invalidVals, 2] = np.NAN
            f23[invalidVals, 0] = np.NAN
            f23[invalidVals, 1] = np.NAN
            f23[invalidVals, 2] = np.NAN
        # determine stresses
        stresses[used, 0] = fplus[used, 0] + fminus[used, 0]
        stresses[used, 1] = fplus[used, 0] - fminus[used, 0]
        stresses[used, 2] = f13[used, 0]
        stresses[used, 3] = f23[used, 0]
        # determine error values
        errVals[used, 0] = np.abs((fplus[used, 2] + fminus[used, 2]) -
                                  (fplus[used, 1] + fminus[used, 1])) / 2
        errVals[used, 1] = np.abs((fplus[used, 2] - fminus[used, 2]) -
                                  (fplus[used, 1] - fminus[used, 1])) / 2
        errVals[used, 2] = np.abs(f13[used, 2] - f13[used, 1]) / 2
        errVals[used, 3] = np.abs(f23[used, 2] - f23[used, 1]) / 2
        # also determine s33
        minVal, minPos = bf.min(abs(psiVals[tauValsValid] - psiStar))
        tauS33 = np.mean(
            tauVals[minPos])  # tau equivalent to condition at psiStar
        # leftVal, leftPos = bf.max(psiVals[psiVals < psiStar])
        # rightVal, rightPos = bf.min(psiVals[psiVals > psiStar])
        # tauS33 = np.interp(psiStar, [leftVal, rightVal], [tauVals[leftPos], tauVals[rightPos]])
        aStarVal = conv.latticeDists2aVals2(dStarVal, hklVal)
        if a0Val is None or a0Val == 0:
            s33 = 0
            ds33 = 0
        else:
            s33 = calcSigma33(aStarVal, a0Val, s1Val, hs2Val)
            ds33 = 2 * mErr**0.5 / (hs2Val * dStarVal)
        resData = {
            'tauRes': tauRes,
            'stresses': stresses,
            'errVals': errVals,
            'validCounter': validCounter,
            'tauS33': tauS33,
            'dStar100': aStarVal,
            'dStar100Err': 2 * bErr**0.5,
            's33': s33,
            'dev_s33': ds33
        }
    return resData
def calcEtaTau(mu, tau, tth, psi):
    th = tth / 2
    return bc.asind(2 * mu * tau * bc.sind(th) * bc.cosd(psi) - bc.sind(th) ** 2 + bc.sind(psi) ** 2) ** 0.5 / \
        (bc.cosd(th) * bc.sind(psi))
def s11s22FreeOrientation(s1, hs2):
    return bc.asind(-2 * s1 / hs2)**0.5
def s33FreeOrientation(s1, hs2, dPsi0, d0, dStar, dPlus):
    return bc.asind(
        (dPsi0 - d0) * calcF33(s1, hs2) / hs2 * (dStar - dPlus))**0.5
Esempio n. 6
0
def latticeDists2angles(latticeDists, wavelength):
    angles = 2 * bc.asind(wavelength / (2 * latticeDists))
    useful = np.nonzero(np.imag(angles) == 0)
    return angles, useful