<commit_before># LIBTBX_PRE_DISPATCHER_INCLUDE_SH export PHENIX_GUI_ENVIRONMENT=1
# LIBTBX_PRE_DISPATCHER_INCLUDE_SH export BOOST_ADAPTBX_FPE_DEFAULT=1

# DIALS_ENABLE_COMMAND_LINE_COMPLETION
from __future__ import division
from gltbx import wx_viewer
import copy
import wx
import wxtbx.utils
from gltbx.gl import *
import gltbx
from scitbx.math import minimum_covering_sphere
from scitbx.array_family import flex
import libtbx.phil

help_message = '''

Visualise the strong spots from spotfinding in reciprocal space.

Examples::

  dials.reciprocal_lattice_viewer datablock.json strong.pickle

  dials.reciprocal_lattice_viewer experiments.json indexed.pickle

'''

phil_scope= libtbx.phil.parse("""
  data = None
    .type = path
    .optional = False
  reverse_phi = False
    .type = bool
    .optional = True
  beam_centre = None
    .type = floats(size=2)
    .help = "Fast, slow beam centre coordinates (mm)."
  show_rotation_axis = False
    .type = bool
  show_beam_vector = False
    .type = bool
  d_min = None
    .type = float(value_min=0.0)
  display = *all unindexed indexed
    .type = choice
  outlier_display = outliers inliers
    .type = choice
  marker_size = 5
    .type = int(value_min=1)
  experiment_ids = None
    .type = ints(value_min=-1)
""")

def settings () :
  return phil_scope.fetch().extract()

class render_3d(object):

  def __init__(self):
    self.reflections = None
    self.goniometer_orig = None

  def load_models(self, imagesets, reflections):
    self.imagesets = imagesets
    self.reflections_input = reflections
    if self.imagesets[0].get_goniometer() is not None:
      self.viewer.set_rotation_axis(
        self.imagesets[0].get_goniometer().get_rotation_axis())
    self.viewer.set_beam_vector(self.imagesets[0].get_beam().get_s0())

    detector = self.imagesets[0].get_detector()
    beam = self.imagesets[0].get_beam()
    if self.settings.beam_centre is None:
      try:
        panel_id, self.settings.beam_centre \
          = detector.get_ray_intersection(beam.get_s0())
      except RuntimeError:
        pass
    else:
      from dxtbx.model.detector_helpers import set_mosflm_beam_centre
      set_mosflm_beam_centre(detector, beam, tuple(reversed(
        self.settings.beam_centre)))
    self.map_points_to_reciprocal_space()
    self.set_points()

  def map_points_to_reciprocal_space(self):
    goniometer = self.imagesets[0].get_goniometer()
    if self.goniometer_orig is not None and not self.settings.reverse_phi:
      self.imagesets[0].set_goniometer(self.goniometer_orig)
      self.goniometer_orig = None
    elif goniometer is not None and self.settings.reverse_phi:
      self.goniometer_orig = copy.deepcopy(goniometer)
      goniometer.set_rotation_axis([-i for i in goniometer.get_rotation_axis()])
    from dials.algorithms.indexing import indexer

    from dials.array_family import flex
    reflections = flex.reflection_table()
    for i, imageset in enumerate(self.imagesets):
      if 'imageset_id' in self.reflections_input:
        sel = (self.reflections_input['imageset_id'] == i)
      else:
        sel = (self.reflections_input['id'] == i)
      if isinstance(self.reflections_input['id'], flex.size_t):
        self.reflections_input['id'] = self.reflections_input['id'].as_int()
      refl = indexer.indexer_base.map_spots_pixel_to_mm_rad(
        self.reflections_input.select(sel),
        imageset.get_detector(), imageset.get_scan())

      indexer.indexer_base.map_centroids_to_reciprocal_space(
        refl, imageset.get_detector(), imageset.get_beam(),
        imageset.get_goniometer())
      reflections.extend(refl)
      self.reflections = reflections

  def set_points(self):
    reflections = self.reflections

    if reflections.has_key('miller_index'):
      indexed_sel = reflections.get_flags(reflections.flags.indexed)
      if self.settings.display == 'indexed':
        reflections = reflections.select(indexed_sel)
      elif self.settings.display == 'unindexed':
        reflections = reflections.select(~indexed_sel)

      outlier_sel = reflections.get_flags(reflections.flags.centroid_outlier)
      if self.settings.outlier_display == 'outliers':
        reflections = reflections.select(outlier_sel)
      if self.settings.outlier_display == 'inliers':
        reflections = reflections.select(~outlier_sel)

      if self.settings.experiment_ids:
        sel = flex.bool(len(reflections), False)
        for i in self.settings.experiment_ids:
          sel.set_selected(reflections['id'] == i, True)
        reflections = reflections.select(sel)

    d_spacings = 1/reflections['rlp'].norms()
    if self.settings.d_min is not None:
      reflections = reflections.select(d_spacings > self.settings.d_min)
    else:
      self.settings.d_min = flex.min(d_spacings)
    points = reflections['rlp'] * 100
    self.viewer.set_points(points)
    colors = flex.vec3_double(len(points), (1,1,1))

    if len(points):
      # suggested colorblind color pallet
      # sorry if you have > 8 lattices!
      palette = flex.vec3_double((
        (255,255,255), (230,159,0), (86,180,233), (0,158,115),
        (240,228,66), (0,114,178), (213,94,0), (204,121,167)))
      palette *= (1/255)
      assert flex.max(reflections['id']) < 7
      for i in range(-1, flex.max(reflections['id'])+1):
        colors.set_selected(reflections['id'] == i, palette[i+1])
    self.viewer.set_colors(colors)


class ReciprocalLatticeViewer(wx.Frame, render_3d):
  def __init__(self, *args, **kwds):
    wx.Frame.__init__(self, *args, **kwds)
    render_3d.__init__(self)
    self.parent = self.GetParent()
    self.statusbar = self.CreateStatusBar()
    self.sizer = wx.BoxSizer(wx.HORIZONTAL)

    app = wx.GetApp()
    if (getattr(app, "settings", None) is not None) :
      # XXX copying the initial settings avoids awkward interactions when
      # multiple viewer windows are opened
      self.settings = copy.deepcopy(app.settings)
    else :
      self.settings = settings()

    self.create_settings_panel()
    self.sizer.Add(self.settings_panel, 0, wx.EXPAND)
    self.create_viewer_panel()
    self.sizer.Add(self.viewer, 1, wx.EXPAND|wx.ALL)
    #self.SetupToolbar()
    #self.SetupMenus()
    #self.add_view_specific_functions()<commit_msg>remove limitation of 7 experiments/imagesets; instead recycle colours<commit_after># LIBTBX_PRE_DISPATCHER_INCLUDE_SH export PHENIX_GUI_ENVIRONMENT=1
# LIBTBX_PRE_DISPATCHER_INCLUDE_SH export BOOST_ADAPTBX_FPE_DEFAULT=1

# DIALS_ENABLE_COMMAND_LINE_COMPLETION
from __future__ import division
from gltbx import wx_viewer
import copy
import wx
import wxtbx.utils
from gltbx.gl import *
import gltbx
from scitbx.math import minimum_covering_sphere
from scitbx.array_family import flex
import libtbx.phil

help_message = '''

Visualise the strong spots from spotfinding in reciprocal space.

Examples::

  dials.reciprocal_lattice_viewer datablock.json strong.pickle

  dials.reciprocal_lattice_viewer experiments.json indexed.pickle

'''

phil_scope= libtbx.phil.parse("""
  data = None
    .type = path
    .optional = False
  reverse_phi = False
    .type = bool
    .optional = True
  beam_centre = None
    .type = floats(size=2)
    .help = "Fast, slow beam centre coordinates (mm)."
  show_rotation_axis = False
    .type = bool
  show_beam_vector = False
    .type = bool
  d_min = None
    .type = float(value_min=0.0)
  display = *all unindexed indexed
    .type = choice
  outlier_display = outliers inliers
    .type = choice
  marker_size = 5
    .type = int(value_min=1)
  experiment_ids = None
    .type = ints(value_min=-1)
""")

def settings () :
  return phil_scope.fetch().extract()

class render_3d(object):

  def __init__(self):
    self.reflections = None
    self.goniometer_orig = None

  def load_models(self, imagesets, reflections):
    self.imagesets = imagesets
    self.reflections_input = reflections
    if self.imagesets[0].get_goniometer() is not None:
      self.viewer.set_rotation_axis(
        self.imagesets[0].get_goniometer().get_rotation_axis())
    self.viewer.set_beam_vector(self.imagesets[0].get_beam().get_s0())

    detector = self.imagesets[0].get_detector()
    beam = self.imagesets[0].get_beam()
    if self.settings.beam_centre is None:
      try:
        panel_id, self.settings.beam_centre \
          = detector.get_ray_intersection(beam.get_s0())
      except RuntimeError:
        pass
    else:
      from dxtbx.model.detector_helpers import set_mosflm_beam_centre
      set_mosflm_beam_centre(detector, beam, tuple(reversed(
        self.settings.beam_centre)))
    self.map_points_to_reciprocal_space()
    self.set_points()

  def map_points_to_reciprocal_space(self):
    goniometer = self.imagesets[0].get_goniometer()
    if self.goniometer_orig is not None and not self.settings.reverse_phi:
      self.imagesets[0].set_goniometer(self.goniometer_orig)
      self.goniometer_orig = None
    elif goniometer is not None and self.settings.reverse_phi:
      self.goniometer_orig = copy.deepcopy(goniometer)
      goniometer.set_rotation_axis([-i for i in goniometer.get_rotation_axis()])
    from dials.algorithms.indexing import indexer

    from dials.array_family import flex
    reflections = flex.reflection_table()
    for i, imageset in enumerate(self.imagesets):
      if 'imageset_id' in self.reflections_input:
        sel = (self.reflections_input['imageset_id'] == i)
      else:
        sel = (self.reflections_input['id'] == i)
      if isinstance(self.reflections_input['id'], flex.size_t):
        self.reflections_input['id'] = self.reflections_input['id'].as_int()
      refl = indexer.indexer_base.map_spots_pixel_to_mm_rad(
        self.reflections_input.select(sel),
        imageset.get_detector(), imageset.get_scan())

      indexer.indexer_base.map_centroids_to_reciprocal_space(
        refl, imageset.get_detector(), imageset.get_beam(),
        imageset.get_goniometer())
      reflections.extend(refl)
      self.reflections = reflections

  def set_points(self):
    reflections = self.reflections

    if reflections.has_key('miller_index'):
      indexed_sel = reflections.get_flags(reflections.flags.indexed)
      if self.settings.display == 'indexed':
        reflections = reflections.select(indexed_sel)
      elif self.settings.display == 'unindexed':
        reflections = reflections.select(~indexed_sel)

      outlier_sel = reflections.get_flags(reflections.flags.centroid_outlier)
      if self.settings.outlier_display == 'outliers':
        reflections = reflections.select(outlier_sel)
      if self.settings.outlier_display == 'inliers':
        reflections = reflections.select(~outlier_sel)

      if self.settings.experiment_ids:
        sel = flex.bool(len(reflections), False)
        for i in self.settings.experiment_ids:
          sel.set_selected(reflections['id'] == i, True)
        reflections = reflections.select(sel)

    d_spacings = 1/reflections['rlp'].norms()
    if self.settings.d_min is not None:
      reflections = reflections.select(d_spacings > self.settings.d_min)
    else:
      self.settings.d_min = flex.min(d_spacings)
    points = reflections['rlp'] * 100
    self.viewer.set_points(points)
    colors = flex.vec3_double(len(points), (1,1,1))

    if len(points):
      # suggested colorblind color pallet
      # sorry if you have > 8 lattices!
      palette = flex.vec3_double((
        (255,255,255), (230,159,0), (86,180,233), (0,158,115),
        (240,228,66), (0,114,178), (213,94,0), (204,121,167)))
      palette *= (1/255)
      n = palette.size() - 1
      for i in range(-1, flex.max(reflections['id'])+1):
        colors.set_selected(reflections['id'] == i, palette[(i%n)+1])
    self.viewer.set_colors(colors)


class ReciprocalLatticeViewer(wx.Frame, render_3d):
  def __init__(self, *args, **kwds):
    wx.Frame.__init__(self, *args, **kwds)
    render_3d.__init__(self)
    self.parent = self.GetParent()
    self.statusbar = self.CreateStatusBar()
    self.sizer = wx.BoxSizer(wx.HORIZONTAL)

    app = wx.GetApp()
    if (getattr(app, "settings", None) is not None) :
      # XXX copying the initial settings avoids awkward interactions when
      # multiple viewer windows are opened
      self.settings = copy.deepcopy(app.settings)
    else :
      self.settings = settings()

    self.create_settings_panel()
    self.sizer.Add(self.settings_panel, 0, wx.EXPAND)
    self.create_viewer_panel()
    self.sizer.Add(self.viewer, 1, wx.EXPAND|wx.ALL)
    #self.SetupToolbar()
    #self.SetupMenus()
    #self.add_view_specific_functions()
{'fraction_non_alphanumeric': 0.109800796812749, 'fraction_numerical': 0.016175298804780875, 'mean_word_length': 3.6160353070981976, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '514549', 'n_tokens_mistral': 4463, 'n_tokens_neox': 4182, 'n_words': 792}