### # Copyright 2008-2011 Diamond Light Source Ltd. # This file is part of Diffcalc. # # Diffcalc is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Diffcalc is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Diffcalc. If not, see . ### from copy import deepcopy import datetime # @UnusedImport for the eval below from diffcalc.util import DiffcalcException, bold from diffcalc.hkl.vlieg.geometry import VliegPosition class _Reflection: """A reflection""" def __init__(self, h, k, l, position, energy, tag, time): self.h = float(h) self.k = float(k) self.l = float(l) self.pos = position self.tag = tag self.energy = float(energy) # energy=12.39842/lambda self.wavelength = 12.3984 / self.energy self.time = time # Saved as e.g. repr(datetime.now()) def __str__(self): return ("energy=%-6.3f h=%-4.2f k=%-4.2f l=%-4.2f alpha=%-8.4f " "delta=%-8.4f gamma=%-8.4f omega=%-8.4f chi=%-8.4f " "phi=%-8.4f %-s %s" % (self.energy, self.h, self.k, self.l, self.pos.alpha, self.pos.delta, self.pos.gamma, self.pos.omega, self.pos.chi, self.pos.phi, self.tag, self.time)) class ReflectionList: def __init__(self, diffractometerPluginObject, externalAngleNames, reflections=None, multiplier=1): self._geometry = diffractometerPluginObject self._externalAngleNames = externalAngleNames self._reflist = reflections if reflections else [] self._multiplier = multiplier def get_tag_index(self, idx): _tag_list = [ref.tag for ref in self._reflist] try: num = _tag_list.index(idx) except ValueError: if isinstance(idx, int): if idx < 1 or idx > len(self._reflist): raise IndexError("Reflection index is out of range") else: num = idx - 1 else: raise IndexError("Reflection index not found") return num def add_reflection(self, h, k, l, position, energy, tag, time): """adds a reflection, position in degrees """ if type(position) in (list, tuple): try: position = self._geometry.create_position(*position) except AttributeError: position = VliegPosition(*position) self._reflist += [_Reflection(h, k, l, position, energy, tag, time.__repr__())] def edit_reflection(self, idx, h, k, l, position, energy, tag, time): """num starts at 1""" try: num = self.get_tag_index(idx) except IndexError: raise DiffcalcException("There is no reflection " + repr(idx) + " to edit.") if type(position) in (list, tuple): position = VliegPosition(*position) self._reflist[num] = _Reflection(h, k, l, position, energy, tag, time.__repr__()) def getReflection(self, idx): """ getReflection(idx) --> ( [h, k, l], position, energy, tag, time ) -- position in degrees """ num = self.get_tag_index(idx) r = deepcopy(self._reflist[num]) # for convenience return [r.h, r.k, r.l], deepcopy(r.pos), r.energy, r.tag, eval(r.time) def get_reflection_in_external_angles(self, idx): """getReflection(num) --> ( [h, k, l], (angle1...angleN), energy, tag ) -- position in degrees""" num = self.get_tag_index(idx) r = deepcopy(self._reflist[num]) # for convenience externalAngles = self._geometry.internal_position_to_physical_angles(r.pos) result = [r.h, r.k, r.l], externalAngles, r.energy, r.tag, eval(r.time) return result def removeReflection(self, idx): num = self.get_tag_index(idx) del self._reflist[num] def swap_reflections(self, idx1, idx2): num1 = self.get_tag_index(idx1) num2 = self.get_tag_index(idx2) orig1 = self._reflist[num1] self._reflist[num1] = self._reflist[num2] self._reflist[num2] = orig1 def __len__(self): return len(self._reflist) def __str__(self): return '\n'.join(self.str_lines()) def str_lines(self): axes = tuple(s.upper() for s in self._externalAngleNames) if not self._reflist: return [" <<< none specified >>>"] lines = [] format = (" %6s %5s %5s %5s " + "%8s " * len(axes) + " TAG") values = ('ENERGY', 'H', 'K', 'L') + axes lines.append(bold(format % values)) for n in range(1, len(self._reflist) + 1): ref_tuple = self.get_reflection_in_external_angles(n) [h, k, l], externalAngles, energy, tag, _ = ref_tuple if tag is None: tag = "" format = (" %2d %6.3f % 4.2f % 4.2f % 4.2f " + "% 8.4f " * len(axes) + " %s") values = (n, energy / self._multiplier, h, k, l) + externalAngles + (tag,) lines.append(format % values) return lines