Esempio n. 1
0
 def get_upper_limit(self, name):
     '''returns upper limit by axis name. Limit may be None if not set
     '''
     try:
         scn = self.diffhw.getGroupMember(name)
     except AttributeError:
         scn = self.diffhw.getFieldScannable(name)
     try:
         limit = scn.getUpperInnerLimit()
         return limit
     except AttributeError:
         pass
     try:
         limits = scn.getUpperGdaLimits()
     except AttributeError:
         raise DiffcalcException(
             "Cannot read upper limit for scannable {}".format(name))
     try:
         if len(limits) != 1:
             raise DiffcalcException(
                 "Upper limit for scannable {} has {} limit values".format(
                     name, len(limits)))
         return limits[0]
     except TypeError:
         return limits
Esempio n. 2
0
    def calculate_UB_from_orientation(self):
        """
        Calculate orientation matrix. Uses first two crystal orientations.
        """

        # Major variables:
        # h1, h2: user input reciprical lattice vectors of the two reflections
        # h1c, h2c: user input vectors in cartesian crystal plane
        # pos1, pos2: measured diffractometer positions of the two reflections
        # u1a, u2a: measured reflection vectors in alpha frame
        # u1p, u2p: measured reflection vectors in phi frame

        # Get hkl and angle values for the first two crystal orientations
        if self._state.orientlist is None:
            raise DiffcalcException("Cannot calculate a U matrix until a "
                                    "UBCalculation has been started with "
                                    "'newub'")
        try:
            (h1, x1, _, _) = self._state.orientlist.getOrientation(1)
            (h2, x2, _, _) = self._state.orientlist.getOrientation(2)
        except IndexError:
            raise DiffcalcException(
                "Two crystal orientations are required to calculate a U matrix"
            )
        h1 = matrix([h1]).T  # row->column
        h2 = matrix([h2]).T
        u1p = matrix([x1]).T
        u2p = matrix([x2]).T

        self._calc_UB(h1, h2, u1p, u2p)
Esempio n. 3
0
    def fit_ub_matrix(self, *args):
        if args is None:
            raise DiffcalcException(
                "Please specify list of reference reflection indices.")
        if len(args) < 3:
            raise DiffcalcException(
                "Need at least 3 reference reflections to fit UB matrix.")

        if len(self._state.crystal.get_lattice_params()[1]) == 6:
            new_u, uc_params = self._fit_ub_matrix_uncon(*args)
        else:
            refl_list = []
            for idx in args:
                try:
                    hkl_vals, pos, en, _, _ = self.get_reflection(idx)
                    pos.changeToRadians()
                    refl_list.append((
                        hkl_vals,
                        pos,
                        en,
                    ))
                except IndexError:
                    raise DiffcalcException(
                        "Cannot read reflection data for index %s" % str(idx))
            print "Fitting crystal lattice parameters..."
            new_lattice = fit_crystal(self._state.crystal, refl_list)
            print "Fitting orientation matrix..."
            new_u = fit_u_matrix(self._U, new_lattice, refl_list)
            uc_params = (self._state.crystal.getLattice()[0],
                         ) + new_lattice.getLattice()[1:]
        return new_u, uc_params
Esempio n. 4
0
def __conic_th_to_hkl(self, params):
    from diffcalc.dc import dcyou as _dc
    from diffcalc.util import norm3, solve_h_fixed_q, solve_k_fixed_q
    import __main__

    try:
        r, th, h0, k0 = params
    except TypeError:
        raise DiffcalcException("Invalid number of input parameters.")
    if not (th >= 0 and th < 180):
        raise DiffcalcException("Value of th should be n [0, 180) range")
    sin_th = sin(th * TORAD)
    cos_th = cos(th * TORAD)
    a = sin_th
    b = -cos_th
    c = 0
    d = h0 * sin_th - k0 * cos_th
    h, k, l = __main__.hkl.getPosition()[:3]
    hkl_nphi = _dc._ub.ubcalc._UB * matrix([[h], [k], [l]])
    qval = norm3(hkl_nphi)**2
    if th > 45.:
        k = k0 + r * sin_th
        hkl = solve_k_fixed_q(k, qval, _dc._ub.ubcalc._UB, (a, b, c, d))
    else:
        h = h0 + r * cos_th
        hkl = solve_h_fixed_q(h, qval, _dc._ub.ubcalc._UB, (a, b, c, d))
    return hkl
Esempio n. 5
0
    def asynchronousMoveTo(self, newpos):

        pos = self.diffhw.getPosition()  # a tuple
        (hkl_pos , _) = self._diffcalc.angles_to_hkl(pos)

        nref_hkl = [i[0] for i in self._diffcalc._ub.ubcalc.n_hkl.tolist()]
        pol, az_nref, sc = self._diffcalc._ub.ubcalc.calc_offset_for_hkl(hkl_pos, nref_hkl)
        if pol < SMALL:
            az_nref = 0
        sc_nref_hkl = [sc * v for v in nref_hkl]

        _ubm = self._diffcalc._ub.ubcalc._get_UB()
        qvec = _ubm * matrix(hkl_pos).T
        qvec_rlu = sqrt(dot3(qvec, qvec)) * self._diffcalc._ub.ubcalc.get_hkl_plane_distance(nref_hkl) / (2.*pi)

        try:
            newpol = acos(bound(newpos / qvec_rlu))
        except AssertionError:
            raise DiffcalcException("Scattering vector projection value of %.5f r.l.u. unreachable." % newpos)

        try:
            hkl_offset = self._diffcalc._ub.ubcalc.calc_hkl_offset(*sc_nref_hkl, pol=newpol, az=az_nref)
            (pos, _) = self._diffcalc.hkl_to_angles(*hkl_offset)
        except DiffcalcException as e:
            if DEBUG:
                raise
            else:
                raise DiffcalcException(e.message)

        self.diffhw.asynchronousMoveTo(pos)
Esempio n. 6
0
 def set_constraint(self, name, value):  # @ReservedAssignment
     ext_name = settings.geometry.map_to_external_name(name)
     if self.is_constraint_fixed(name):
         raise DiffcalcException('%s constraint cannot be changed' %
                                 ext_name)
     self._check_constraint_settable(name)
     #        if name in self._tracking:
     #            raise DiffcalcException(
     #                "Could not set %s as this constraint is configured to track "
     #                "its associated\nphysical angle. First remove this tracking "
     #                "(use 'untrack %s').""" % (name, name))
     old_value = self.get_constraint(name)
     try:
         old_str = '---' if old_value is None else str(old_value)
     except Exception:
         old_str = '---'
     try:
         self._constrained[name] = float(value) * TORAD
     except Exception:
         raise DiffcalcException(
             'Cannot set %s constraint. Invalid input value.' % ext_name)
     try:
         new_str = '---' if value is None else str(value)
     except Exception:
         new_str = '---'
     return "%s : %s --> %s" % (name, old_str, new_str)
Esempio n. 7
0
    def _calc_remaining_detector_angles(self, constraint_name,
                                        constraint_value, theta):
        """Return delta, nu and qaz given one detector angle
        """
        #                                                         (section 5.1)
        # Find qaz using various derivations of 17 and 18
        if constraint_name == 'delta':
            delta = constraint_value
            sin_2theta = sin(2 * theta)
            if is_small(sin_2theta):
                raise DiffcalcException(
                    'No meaningful scattering vector (Q) can be found when '
                    'theta is so small (%.4f).' % theta * TODEG)
            qaz = asin(bound(sin(delta) / sin_2theta))              # (17 & 18)

        elif constraint_name == NUNAME:
            nu = constraint_value
#            cos_delta = cos(2*theta) / cos(nu)#<--fails when nu = 90
#            delta = acos(bound(cos_delta))
#            tan
            sin_2theta = sin(2 * theta)
            if is_small(sin_2theta):
                raise DiffcalcException(
                    'No meaningful scattering vector (Q) can be found when '
                    'theta is so small (%.4f).' % theta * TODEG)
            cos_qaz = tan(nu) / tan(2 * theta)
            if abs(cos_qaz) > 1 + SMALL:
                raise DiffcalcException(
                    'The specified %s=%.4f is greater than the 2theta (%.4f)'
                    % (NUNAME, nu, theta))
            qaz = acos(bound(cos_qaz))

        elif constraint_name == 'qaz':
            qaz = constraint_value

        else:
            raise ValueError(
                constraint_name + ' is not an explicit detector angle '
                '(naz cannot be handled here)')

        if constraint_name != NUNAME:
            nu = atan2(sin(2 * theta) * cos(qaz), cos(2 * theta))

        if constraint_name != 'delta':
            cos_qaz = cos(qaz)
            if not is_small(cos_qaz):  # TODO: switch methods at 45 deg?
                delta = atan2(sin(qaz) * sin(nu), cos_qaz)
            else:
                # qaz is close to 90 (a common place for it)
                delta = sign(qaz) * acos(bound(cos(2 * theta) / cos(nu)))

        return delta, nu, qaz
Esempio n. 8
0
 def constrain(self, name):
     if self.is_constraint_fixed(name):
         raise DiffcalcException('%s is not a valid constraint name' % name)
     if name in self.all:
         return "%s is already constrained." % name.capitalize()
     elif name in det_constraints:
         return self._constrain_detector(name)
     elif name in ref_constraints:
         return self._constrain_reference(name)
     elif name in samp_constraints:
         return self._constrain_sample(name)
     else:
         raise DiffcalcException("%s is not a valid constraint name. Type 'con' for a table of constraint name" % name)
Esempio n. 9
0
 def _calc_theta(self, h_phi, wavelength):
     """Calculate theta using Equation1
     """
     q_length = norm(h_phi)
     if q_length == 0:
         raise DiffcalcException('Reflection is unreachable as |Q| is 0')
     wavevector = 2 * pi / wavelength
     try:
         theta = asin(q_length / (2 * wavevector))
     except ValueError:
         raise DiffcalcException(
             'Reflection is unreachable as |Q| is too long')
     return theta
Esempio n. 10
0
 def _check_constraint_settable(self, name):
     if name not in all_constraints:
         raise DiffcalcException(
             'Could not set %(name)s. This is not an available '
             'constraint.' % locals())
     elif name not in self.all.keys():
         raise DiffcalcException(
             'Could not set %(name)s. This is not currently '
             'constrained.' % locals())
     elif name in valueless_constraints:
         raise DiffcalcException(
             'Could not set %(name)s. This constraint takes no '
             'value.' % locals())
Esempio n. 11
0
 def _check_constraint_settable(self, name):
     ext_name = settings.geometry.map_to_external_name(name)
     if name not in all_constraints:
         raise DiffcalcException(
             'Could not set %(ext_name)s. This is not an available '
             'constraint.' % locals())
     elif name not in self.all.keys():
         raise DiffcalcException(
             'Could not set %(ext_name)s. This is not currently '
             'constrained.' % locals())
     elif name in valueless_constraints:
         raise DiffcalcException(
             'Could not set %(ext_name)s. This constraint takes no '
             'value.' % locals())
Esempio n. 12
0
 def setTrackParameter(self, name, switch):
     if not name in self._parameters.keys():
         raise DiffcalcException("No fixed parameter %s is used by the "
                                 "diffraction calculator" % name)
     if not name in self._trackableParameters:
         raise DiffcalcException("Parameter %s is not trackable" % name)
     if not self._isParameterChangeable(name):
         print("WARNING: Parameter %s is not used in mode %i" %
               (name, self._mode.index))
     if switch:
         if name not in self._trackedParameters:
             self._trackedParameters.append(name)
     else:
         if name in self._trackedParameters:
             self._trackedParameters.remove(name)
Esempio n. 13
0
    def simulateMoveTo(self, hkl):
        if type(hkl) not in (list, tuple):
            raise ValueError('sr2 device expects four inputs')
        if len(hkl) != 4:
            raise ValueError('sr2 device expects four inputs')
        az = hkl[-1] * TORAD
        try:
            _hkl_ref = self._diffcalc._ub.ubcalc.get_reflection(1)[0]
        except IndexError:
            raise DiffcalcException("Please add one reference reflection into the reflection list.")
        pol, _, sc = self._diffcalc._ub.ubcalc.calc_offset_for_hkl(hkl[:3], _hkl_ref)
        hkl_sc= [sc * val for val in _hkl_ref]
        hkl_offset = self._diffcalc._ub.ubcalc.calc_hkl_offset(*hkl_sc, pol=pol, az=az)
        (pos, params) = self._diffcalc.hkl_to_angles(*hkl_offset)

        width = max(len(k) for k in (params.keys() + list(self.diffhw.getInputNames())))
        fmt = '  %' + str(width) + 's : % 9.4f'

        lines = ['simulated hkl: %9.4f  %.4f  %.4f' % (hkl_offset[0],hkl_offset[1],hkl_offset[2]),
                 self.diffhw.getName() + ' would move to:']
        for idx, name in enumerate(self.diffhw.getInputNames()):
            lines.append(fmt % (name, pos[idx]))
        lines[-1] = lines[-1] + '\n'
        for k in sorted(params):
            lines.append(fmt % (k, params[k]))
        return '\n'.join(lines)
Esempio n. 14
0
def __hkl_to_conic_h(self, hkl):
    h, _, _ = hkl
    try:
        a, b, c, d = self.cached_params
    except TypeError:
        raise DiffcalcException("hkl constraint values not set.")
    return (h, a, b, c, d)
Esempio n. 15
0
 def unconstrain(self, name):
     if self.is_constraint_fixed(name):
         raise DiffcalcException('%s is not a valid constraint name')
     if name in self._constrained:
         del self._constrained[name]
     else:
         return "%s was not already constrained." % name.capitalize()
Esempio n. 16
0
def _raise_multiple_detector_solutions_found(delta_nu_pairs):
    assert len(delta_nu_pairs) > 1
    delta_nu_pairs_degrees = [[v * TODEG for v in pair]
                                  for pair in delta_nu_pairs]
    raise DiffcalcException(
        'Multiple detector solutions were found: delta, %s = %s, '
        'please constrain detector limits' % (NUNAME, delta_nu_pairs_degrees))
Esempio n. 17
0
 def normalise(m):
     d = norm(m)
     if d < SMALL:
         raise DiffcalcException(
             "Invalid UB reference data. Please check that the specified "
             "reference reflections/orientations are not parallel.")
     return m / d
Esempio n. 18
0
 def get_energy(self):
     """energy = get_energy() -- returns energy in kEv  """
     if self._wavelength is None:
         raise DiffcalcException(
             "Energy or wavelength have not been set")
     return (12.39842 /
             (self._wavelength * self.energyScannableMultiplierToGetKeV))
Esempio n. 19
0
    def add_reflection(self, h, k, l, position, energy, tag, time):
        """Add a reference reflection.
        
        Adds a reflection position in degrees and in the
        systems internal representation.
        
        Parameters
        ----------
        h : number
            h index of the reflection
        k : number
            k index of the reflection
        l : number
            l index of the reflection
        position: :obj:`list` or :obj:`tuple` of numbers
            list of diffractometer angles in internal representation in degrees
        energy : float
            energy of the x-ray beam
        tag : str
            identifying tag for the reflection
        time : :obj:`datetime`
            datetime object
        """
        if self._state.reflist is None:
            raise DiffcalcException("No UBCalculation loaded")
        self._state.reflist.add_reflection(h, k, l, position, energy, tag,
                                           time)
        self.save()  # incase autocalculateUbAndReport fails

        # If second reflection has just been added then calculateUB
        if self.get_reference_count() == 2:
            self._autocalculateUbAndReport()
        self.save()
Esempio n. 20
0
    def set_U_manually(self, m, conv=True):
        """Manually sets U. matrix must be 3*3 Jama or python matrix.
        Turns off aution UB calcualtion."""

        # Check matrix is a 3*3 Jama matrix
        if m.__class__ != matrix:
            m = matrix(m)  # assume its a python matrix
        if m.shape[0] != 3 or m.shape[1] != 3:
            raise ValueError("Expects 3*3 matrix")

        if self._UB is None:
            print "Calculating UB matrix."
        else:
            print "Recalculating UB matrix."

        if conv:
            self._U = self._tobj.transform(m)
        else:
            self._U = m
        self._state.configure_calc_type(manual_U=self._U)
        if self._state.crystal is None:
            raise DiffcalcException(
                "A crystal must be specified before manually setting U")
        self._UB = self._U * self._state.crystal.B
        self.save()
Esempio n. 21
0
 def load(self, name):
     state = self._persister.load(name)
     if isinstance(self._persister, UBCalculationJSONPersister):
         self._state = self._persister.encoder.decode_ubcalcstate(
             state, settings.geometry,
             self._get_diffractometer_axes_names(),
             settings.hardware.energyScannableMultiplierToGetKeV)
         self._state.reference.get_UB = self._get_UB
         self._state.surface.get_UB = self._get_UB
     elif isinstance(self._persister, UBCalculationPersister):
         self._state = state
     else:
         raise DiffcalcException('Unexpected persister type: ' +
                                 str(self._persister))
     if self._state.manual_U is not None:
         self._U = self._state.manual_U
         self._UB = self._U * self._state.crystal.B
         self.save()
     elif self._state.manual_UB is not None:
         self._UB = self._state.manual_UB
         self.save()
     elif self._state.is_okay_to_autocalculate_ub:
         try:
             self.calculate_UB(self._state.or0, self._state.or1)
         except Exception, e:
             print e
Esempio n. 22
0
 def constrain(self, name):
     if name in self.all:
         return "%s is already constrained." % name.capitalize()
     elif name in ref_constraints:
         return self._constrain_reference(name)
     else:
         raise DiffcalcException('%s is not a valid constraint name')
Esempio n. 23
0
 def get_energy(self):
     """energy = get_energy() -- returns energy in keV (NOT eV!) """
     multiplier = self.energyScannableMultiplierToGetKeV
     energy = self.energyhw.getPosition() * multiplier
     if energy is None:
         raise DiffcalcException("Energy has not been set")
     return energy
Esempio n. 24
0
def newub(name=None):
    """newub {'name'} -- start a new ub calculation name
    """
    if name is None:
        # interactive
        name = promptForInput('calculation name')
        while not name:
            print('Please provide non-empty UB calculation name')
            name = promptForInput('calculation name')
        try:
            ubcalc.start_new(name)
        except IOError:
            raise DiffcalcException('Cannot create UB calculation persistence file with name "%s"' % name)
        setlat()
    elif isinstance(name, str):
        if name in ubcalc._persister.list():
            print ("No UB calculation started: There is already a calculation "
                    "called: " + name)
            reply = promptForInput("Load the existing UB calculation '%s'? " % name, 'y')
            if reply in ('y', 'Y', 'yes'):
                loadub(name)
                return
            else:
                reply = promptForInput("Overwrite the existing UB calculation '%s'? " % name, 'y')
                if reply in ('y', 'Y', 'yes'):
                    ubcalc.start_new(name)
                    setlat()
                else:
                    print ("Aborting")
        else:
            # just trying might cause confusion here
            ubcalc.start_new(name)
    else:
        raise TypeError()
Esempio n. 25
0
    def set_U_manually(self, m):
        """Manually sets U. matrix must be 3*3 Jama or python matrix.
        Turns off aution UB calcualtion."""

        # Check matrix is a 3*3 Jama matrix
        if m.__class__ != matrix:
            m = matrix(m)  # assume its a python matrix
        if m.shape[0] != 3 or m.shape[1] != 3:
            raise ValueError("Expects 3*3 matrix")

        if self._UB is None:
            print "Calculating UB matrix."
        else:
            print "Recalculating UB matrix."

        self._state.configure_calc_type(manual_U=m)
        self._U = m
        if self._state.crystal is None:
            raise DiffcalcException(
                "A crystal must be specified before manually setting U")
        self._UB = self._U * self._state.crystal.B
        print(
            "NOTE: A new UB matrix will not be automatically calculated "
            "when the orientation reflections are modified.")
        self.save()
Esempio n. 26
0
 def asynchronousMoveTo(self, new_position):
     report = self.checkPositionValid([
         new_position,
     ])
     if report:
         raise DiffcalcException(report)
     self._current_position = float(new_position)
Esempio n. 27
0
 def asynchronousMoveTo(self, newpos):
     report = self.checkPositionValid([
         newpos,
     ])
     if report:
         raise DiffcalcException(report)
     ScannableBase.asynchronousMoveTo(self, newpos)
Esempio n. 28
0
    def _fit_ub_matrix_uncon(self, *args):
        if args is None:
            raise DiffcalcException(
                "Please specify list of reference reflection indices.")
        if len(args) < 3:
            raise DiffcalcException(
                "Need at least 3 reference reflections to fit UB matrix.")

        x = []
        y = []
        for idx in args:
            try:
                hkl_vals, pos, en, _, _ = self.get_reflection(idx)
            except IndexError:
                raise DiffcalcException(
                    "Cannot read reflection data for index %s" % str(idx))
            pos.changeToRadians()
            x.append(hkl_vals)
            wl = 12.3984 / en
            y_tmp = self._strategy.calculate_q_phi(pos) * 2. * pi / wl
            y.append(y_tmp.T.tolist()[0])

        xm = matrix(x)
        ym = matrix(y)
        b = (xm.T * xm).I * xm.T * ym

        b1, b2, b3 = matrix(b.tolist()[0]), matrix(b.tolist()[1]), matrix(
            b.tolist()[2])
        e1 = b1 / norm(b1)
        e2 = b2 - e1 * dot3(b2.T, e1.T)
        e2 = e2 / norm(e2)
        e3 = b3 - e1 * dot3(b3.T, e1.T) - e2 * dot3(b3.T, e2.T)
        e3 = e3 / norm(e3)

        new_umatrix = matrix(e1.tolist() + e2.tolist() + e3.tolist()).T

        V = dot3(cross3(b1.T, b2.T), b3.T)
        a1 = cross3(b2.T, b3.T) * 2 * pi / V
        a2 = cross3(b3.T, b1.T) * 2 * pi / V
        a3 = cross3(b1.T, b2.T) * 2 * pi / V
        ax, bx, cx = norm(a1), norm(a2), norm(a3)
        alpha = acos(dot3(a2, a3) / (bx * cx)) * TODEG
        beta = acos(dot3(a1, a3) / (ax * cx)) * TODEG
        gamma = acos(dot3(a1, a2) / (ax * bx)) * TODEG

        lattice_name = self._state.crystal.getLattice()[0]
        return new_umatrix, (lattice_name, ax, bx, cx, alpha, beta, gamma)
Esempio n. 29
0
 def checkPositionLength(self, positionArray):
     if len(positionArray) != len(
             self.getHostScannable().getInputNames()):
         raise DiffcalcException(
             "Expected position of length {} but got position of length {}"
             .format(
                 len(self.getHostScannable().getInputNames().length),
                 len(positionArray)))
Esempio n. 30
0
 def constrain(self, name):
     ext_name = settings.geometry.map_to_external_name(name)
     if self.is_constraint_fixed(name):
         raise DiffcalcException('%s constraint cannot be changed' %
                                 ext_name)
     if name in self.all:
         return "%s is already constrained." % ext_name.capitalize()
     elif name in det_constraints:
         return self._constrain_detector(name)
     elif name in ref_constraints:
         return self._constrain_reference(name)
     elif name in samp_constraints:
         return self._constrain_sample(name)
     else:
         raise DiffcalcException(
             "%s is not a valid constraint name. Type 'con' for a table of constraint name"
             % ext_name)