def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() xs.shake_adp() # it must happen before the reparamtrisation is constructed # because the ADP values are read then and only then. connectivity_table = smtbx.utils.connectivity_table(xs) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type=oop.null()) cycles = normal_eqns_solving.naive_iterations( ls, n_max_iterations=10, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-4) assert approx_equal(ls.objective(), 0) # skip next-to-last one to allow for no progress and rounding error n = len(cycles.objective_history) assert cycles.objective_history[0] > cycles.objective_history[n-1],\ cycles.objective_history assert approx_equal(cycles.gradient_norm_history[-1], 0, eps=1e-6) for sc0, sc1 in zip(self.xray_structure.scatterers(), xs.scatterers()): assert approx_equal(sc0.u_star, sc1.u_star)
def exercise_null(): n = oop.null("a", 1, []) assert not n assert isinstance(n.f, oop.null) assert isinstance(n.g(1, b=2), oop.null) h = n.h = 2 assert h == 2 assert isinstance(n.h, oop.null) assert isinstance(n[23085], oop.null) x = n[234] = 2 assert x == 2 assert isinstance(n[234], oop.null)
def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() xs.shake_adp( ) # it must happen before the reparamtrisation is constructed # because the ADP values are read then and only then. connectivity_table = smtbx.utils.connectivity_table(xs) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting(a=0), origin_fixing_restraints_type=oop.null()) try: cycles = normal_eqns_solving.naive_iterations( ls, gradient_threshold=1e-12, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-4) assert approx_equal(ls.objective(), 0) assert cycles.gradient_norm_history[-1] < cycles.gradient_threshold for sc0, sc1 in zip(self.xray_structure.scatterers(), xs.scatterers()): assert approx_equal(sc0.u_star, sc1.u_star) except RuntimeError, err: import re m = re.search( r'^cctbx::adptbx::debye_waller_factor_exp: \s* arg_limit \s+ exceeded' '.* arg \s* = \s* ([\d.eE+-]+)', str(err), re.X) assert m is not None, eval print "Warning: refinement of ADP's diverged" print ' argument to debye_waller_factor_exp reached %s' % m.group( 1) print 'Here is the failing structure' xs.show_summary() xs.show_scatterers() raise self.refinement_diverged()
def exercise_ls_cycles(self): xs = self.xray_structure.deep_copy_scatterers() xs.shake_adp() # it must happen before the reparamtrisation is constructed # because the ADP values are read then and only then. connectivity_table = smtbx.utils.connectivity_table(xs) reparametrisation = constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=connectivity_table) ls = least_squares.crystallographic_ls( self.fo_sq.as_xray_observations(), reparametrisation, weighting_scheme=least_squares.mainstream_shelx_weighting(a=0), origin_fixing_restraints_type=oop.null()) try: cycles = normal_eqns_solving.naive_iterations( ls, gradient_threshold=1e-12, track_all=True) assert approx_equal(ls.scale_factor(), 1, eps=1e-4) assert approx_equal(ls.objective(), 0) assert cycles.gradient_norm_history[-1] < cycles.gradient_threshold for sc0, sc1 in zip(self.xray_structure.scatterers(), xs.scatterers()): assert approx_equal(sc0.u_star, sc1.u_star) except RuntimeError, err: import re m = re.search( r'^cctbx::adptbx::debye_waller_factor_exp: \s* arg_limit \s+ exceeded' '.* arg \s* = \s* ([\d.eE+-]+)', str(err), re.X) assert m is not None, eval print "Warning: refinement of ADP's diverged" print ' argument to debye_waller_factor_exp reached %s' % m.group(1) print 'Here is the failing structure' xs.show_summary() xs.show_scatterers() raise self.refinement_diverged()
def __init__(self, command_stream, builder=None): from libtbx import object_oriented_patterns as oop if builder is None: builder = oop.null() parser.__init__(self, command_stream, builder) self.instructions = {}
def get_control (self, name) : return self._controls.get(name, oop.null())
def process_input_array(self, arr): #array = self.miller_array.deep_copy() array = arr.deep_copy() multiplicities = None if self.merge_equivalents: if self.settings.show_anomalous_pairs: merge = array.merge_equivalents() multiplicities = merge.redundancies() asu, matches = multiplicities.match_bijvoet_mates() mult_plus, mult_minus = multiplicities.hemispheres_acentrics() anom_mult = flex.int( min(p, m) for (p, m) in zip(mult_plus.data(), mult_minus.data())) #flex.min_max_mean_double(anom_mult.as_double()).show() anomalous_multiplicities = miller.array( miller.set(asu.crystal_symmetry(), mult_plus.indices(), anomalous_flag=False), anom_mult) anomalous_multiplicities = anomalous_multiplicities.select( anomalous_multiplicities.data() > 0) array = anomalous_multiplicities multiplicities = anomalous_multiplicities else: merge = array.merge_equivalents() array = merge.array() multiplicities = merge.redundancies() settings = self.settings data = array.data() self.missing_set = oop.null() #if (array.is_xray_intensity_array()): # data.set_selected(data < 0, flex.double(data.size(), 0.)) if (array.is_unique_set_under_symmetry()) and (settings.map_to_asu): array = array.map_to_asu() if (multiplicities is not None): multiplicities = multiplicities.map_to_asu() if (settings.d_min is not None): array = array.resolution_filter(d_min=settings.d_min) if (multiplicities is not None): multiplicities = multiplicities.resolution_filter( d_min=settings.d_min) self.filtered_array = array.deep_copy() if (settings.expand_anomalous): array = array.generate_bijvoet_mates() original_symmetry = array.crystal_symmetry() if (multiplicities is not None): multiplicities = multiplicities.generate_bijvoet_mates() if (self.settings.show_missing): self.missing_set = array.complete_set().lone_set(array) if self.settings.show_anomalous_pairs: self.missing_set = self.missing_set.select( self.missing_set.centric_flags().data(), negate=True) if (settings.expand_to_p1): original_symmetry = array.crystal_symmetry() array = array.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) #array = array.niggli_cell().expand_to_p1() #self.missing_set = self.missing_set.niggli_cell().expand_to_p1() self.missing_set = self.missing_set.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) if (multiplicities is not None): multiplicities = multiplicities.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) data = array.data() self.r_free_mode = False self.phases = flex.double(data.size(), float('nan')) self.radians = flex.double(data.size(), float('nan')) self.ampl = flex.double(data.size(), float('nan')) #if not self.foms: # self.foms = flex.double(data.size(), float('nan')) self.sigmas = None #self.sigmas = flex.double(data.size(), float('nan')) if isinstance(data, flex.bool): self.r_free_mode = True data_as_float = flex.double(data.size(), 0.0) data_as_float.set_selected(data == True, flex.double(data.size(), 1.0)) data = data_as_float self.data = data.deep_copy() else: if isinstance(data, flex.double): self.data = data.deep_copy() elif isinstance(data, flex.complex_double): self.data = data.deep_copy() self.ampl = flex.abs(data) self.phases = flex.arg(data) * 180.0 / math.pi # purge nan values from array to avoid crash in fmod_positive() b = flex.bool([bool(math.isnan(e)) for e in self.phases]) # replace the nan values with an arbitrary float value self.phases = self.phases.set_selected(b, 42.4242) # indicate the coresponding phase/radian is completely undetermnined #self.foms = self.foms.set_selected(b, 0.0) # Now cast negative degrees to equivalent positive degrees self.phases = flex.fmod_positive(self.phases, 360.0) self.radians = flex.arg(data) # replace the nan values with an arbitrary float value self.radians = self.radians.set_selected(b, 0.424242) elif hasattr(array.data(), "as_double"): self.data = array.data().as_double() else: raise RuntimeError("Unexpected data type: %r" % data) if (settings.show_data_over_sigma): if (array.sigmas() is None): raise Sorry("sigmas not defined.") sigmas = array.sigmas() non_zero_sel = sigmas != 0 array = array.select(non_zero_sel) array = array.customized_copy(data=array.data() / array.sigmas()) self.data = array.data() if (multiplicities is not None): multiplicities = multiplicities.select(non_zero_sel) if array.sigmas() is not None: self.sigmas = array.sigmas() else: self.sigmas = None work_array = array work_array.set_info(arr.info()) multiplicities = multiplicities return work_array, multiplicities
self._caller_wait.put(None) else: result = self._callback(*args, **kwds) if (result == False): return False last_iteration = self._queue.get() if (last_iteration): return False return result def resume(self, last_iteration=False): if (self.isAlive()): self._queue.put(last_iteration) return self null_callback = oop.null() class queue_monitor_thread (threading.Thread) : def __init__ (self, q, callback, sleep_interval=1.0) : self.q = q self.cb = callback self._exit = False self._sleep_interval = sleep_interval threading.Thread.__init__(self) def run (self) : t = self._sleep_interval while not self._exit : if (self.q.qsize() > 0) : result = self.q.get(timeout=1) self.cb(result)
def exercise_floating_origin_restraints(self): n = self.n_independent_params eps_zero_rhs = 1e-6 connectivity_table = smtbx.utils.connectivity_table(self.xray_structure) reparametrisation = constraints.reparametrisation( structure=self.xray_structure, constraints=[], connectivity_table=connectivity_table) obs = self.fo_sq.as_xray_observations() ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type=oop.null()) ls.build_up() unrestrained_normal_matrix = ls.normal_matrix_packed_u() assert len(unrestrained_normal_matrix) == n*(n+1)//2 ev = eigensystem.real_symmetric( unrestrained_normal_matrix.matrix_packed_u_as_symmetric()) unrestrained_eigenval = ev.values() unrestrained_eigenvec = ev.vectors() ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.homogeneous_weighting) ls.build_up() # Let's check that the computed singular directions span the same # space as the expected ones singular_test = flex.double() jac = ls.reparametrisation.jacobian_transpose_matching_grad_fc() m = 0 for s in ls.origin_fixing_restraint.singular_directions: assert s.norm() != 0 singular_test.extend(jac*s) m += 1 for s in self.continuous_origin_shift_basis: singular_test.extend(flex.double(s)) m += 1 singular_test.reshape(flex.grid(m, n)) assert self.rank(singular_test) == len(self.continuous_origin_shift_basis) assert ls.opposite_of_gradient()\ .all_approx_equal(0, eps_zero_rhs),\ list(ls.gradient()) restrained_normal_matrix = ls.normal_matrix_packed_u() assert len(restrained_normal_matrix) == n*(n+1)//2 ev = eigensystem.real_symmetric( restrained_normal_matrix.matrix_packed_u_as_symmetric()) restrained_eigenval = ev.values() restrained_eigenvec = ev.vectors() # The eigendecomposition of the normal matrix # for the unrestrained problem is: # A = sum_{0 <= i < n-p-1} lambda_i v_i^T v_i # where the eigenvalues lambda_i are sorted in decreasing order # and p is the dimension of the continous origin shift space. # In particular A v_i = 0, n-p <= i < n. # In the restrained case, it becomes: # A' = A + sum_{n-p <= i < n} mu v_i^T v_i p = len(self.continuous_origin_shift_basis) assert approx_equal(restrained_eigenval[p:], unrestrained_eigenval[:-p], eps=1e-12) assert unrestrained_eigenval[-p]/unrestrained_eigenval[-p-1] < 1e-12 if p > 1: # eigenvectors are stored by rows unrestrained_null_space = unrestrained_eigenvec.matrix_copy_block( i_row=n-p, i_column=0, n_rows=p, n_columns=n) assert self.rank(unrestrained_null_space) == p restrained_space = restrained_eigenvec.matrix_copy_block( i_row=0, i_column=0, n_rows=p, n_columns=n) assert self.rank(restrained_space) == p singular = flex.double( self.continuous_origin_shift_basis) assert self.rank(singular) == p rank_finder = flex.double(n*3*p) rank_finder.resize(flex.grid(3*p, n)) rank_finder.matrix_paste_block_in_place(unrestrained_null_space, i_row=0, i_column=0) rank_finder.matrix_paste_block_in_place(restrained_space, i_row=p, i_column=0) rank_finder.matrix_paste_block_in_place(singular, i_row=2*p, i_column=0) assert self.rank(rank_finder) == p else: # this branch handles the case p=1 # it's necessary to work around a bug in the svd module # ( nx1 matrices crashes the code ) assert approx_equal( restrained_eigenvec[0:n].angle( unrestrained_eigenvec[-n:]) % math.pi, 0) assert approx_equal( unrestrained_eigenvec[-n:].angle( flex.double(self.continuous_origin_shift_basis[0])) % math.pi, 0) # Do the floating origin restraints prevent the structure from floating? xs = self.xray_structure.deep_copy_scatterers() ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting ) barycentre_0 = xs.sites_frac().mean() while True: xs.shake_sites_in_place(rms_difference=0.15) xs.apply_symmetry_sites() barycentre_1 = xs.sites_frac().mean() delta = matrix.col(barycentre_1) - matrix.col(barycentre_0) moved_far_enough = 0 for singular in self.continuous_origin_shift_basis: e = matrix.col(singular[:3]) if not approx_equal(delta.dot(e), 0, eps=0.01, out=None): moved_far_enough += 1 if moved_far_enough: break # one refinement cycle ls.build_up() ls.solve() shifts = ls.step() # That's what floating origin restraints are for! # Note that in the presence of special position, that's different # from the barycentre not moving along the continuous shift directions. # TODO: typeset notes about that subtlety. for singular in self.continuous_origin_shift_basis: assert approx_equal(shifts.dot(flex.double(singular)), 0, eps=1e-12)
def add_controls(self): ''' All the buttoms on the lef hand panel is defined here ''' self._index_span = None self._last_sg_sel = None # # d_min control self.d_min_ctrl = floatspin.FloatSpin(parent=self, increment=0.05, digits=2) self.d_min_ctrl.Bind(wx.EVT_SET_FOCUS, lambda evt: None) if (wx.VERSION >= (2, 9)): # XXX FloatSpin bug in 2.9.2/wxOSX_Cocoa self.d_min_ctrl.SetBackgroundColour(self.GetBackgroundColour()) box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) label = wx.StaticText(self, -1, "High resolution:") box.Add(label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(self.d_min_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(floatspin.EVT_FLOATSPIN, self.OnChangeResolution, self.d_min_ctrl) ##Kau added start self.column_ctrl = oop.null() self.column_ctrl = wx.Choice( self.panel, -1, # choices=["jinga","manga","linga","some lable", "ranga"], choices=[], size=(160, -1)) # self.Bind(wx.EVT_CHOICE, self.OnChangeSpaceGroup, self.array_ctrl) self.Bind(wx.EVT_CHOICE, self.OnChangeColumn, self.column_ctrl) # example_file=os.path.join("combine_4zg3.mtz") box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(wx.StaticText(self.panel, -1, "labels :"), 0, wx.ALL, 5) box.Add(self.column_ctrl, 0, wx.ALL, 5) ##This is to include I/SigI column details self.IoverSigI_ctrl = floatspin.FloatSpin(parent=self, increment=0.25, digits=2) self.IoverSigI_ctrl.Bind(wx.EVT_SET_FOCUS, lambda evt: None) if (wx.VERSION >= (2, 9)): # XXX FloatSpin bug in 2.9.2/wxOSX_Cocoa self.IoverSigI_ctrl.SetBackgroundColour(self.GetBackgroundColour()) box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) label = wx.StaticText(self, -1, "I/SigI:") box.Add(label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(self.IoverSigI_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(floatspin.EVT_FLOATSPIN, self.OnChangeIoverSigI, self.IoverSigI_ctrl) ##Kau added ends # # scale control # box = wx.BoxSizer(wx.HORIZONTAL) # self.panel_sizer.Add(box) # label = wx.StaticText(self, -1, "Scale:") # box.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # self.scale_ctrl = wx.Slider(self, size=(120,-1), style=wx.SL_AUTOTICKS) # self.scale_ctrl.SetMin(0) # self.scale_ctrl.SetMax(16) # self.scale_ctrl.SetTickFreq(4, 1) # self.Bind(wx.EVT_SLIDER, self.OnSetScale, self.scale_ctrl) # for x in [0, 4, 8, 12, 16] : # self.scale_ctrl.SetTick(x) # self.scale_ctrl.SetValue((self.settings.scale * 4) - 4) # box.Add(self.scale_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # # ###Kau added starts here # # information control # box = wx.BoxSizer(wx.HORIZONTAL) # self.panel_sizer.Add(box) # label = wx.StaticText(self, -1, "Information content:") # box.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # self.scale_ctrl = wx.Slider(self, size=(120,-1), style=wx.SL_AUTOTICKS) # self.scale_ctrl.SetMin(0) # self.scale_ctrl.SetMax(16) # self.scale_ctrl.SetTickFreq(4, 1) # self.Bind(wx.EVT_SLIDER, self.OnSetScale, self.scale_ctrl) # for x in [0, 4, 8, 12, 16] : # self.scale_ctrl.SetTick(x) # self.scale_ctrl.SetValue((self.settings.scale * 4) - 4) # box.Add(self.scale_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # # ###Kau added ends here ctrls = self.create_controls(setting="black_background", label="Black background") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) ctrls = self.create_controls(setting="show_axes", label="Show h,k,l axes") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) # ctrls = self.create_controls( # setting="show_data_over_sigma", # label="Use I or F over sigma") # self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) if (not self.is_3d_view): # ctrls = self.create_controls( # setting="uniform_size", # label="Use same radius for all points") # self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) # ctrls = self.create_controls( # setting="sqrt_scale_radii", # label="Scale radii to sqrt(value)") # self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) # ctrls = self.create_controls( # setting="sqrt_scale_colors", # label="Scale colors to sqrt(value)") # self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) self.sg_ctrl = oop.null() if (self.is_3d_view): self.sg_ctrl = wx.Choice(self.panel, -1, choices=[], size=(160, -1)) self.Bind(wx.EVT_CHOICE, self.OnChangeSpaceGroup, self.sg_ctrl) box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(wx.StaticText(self.panel, -1, "Space group:"), 0, wx.ALL, 5) box.Add(self.sg_ctrl, 0, wx.ALL, 5) ctrls = self.create_controls(setting="expand_to_p1", label="Expand data to P1") ctrls2 = self.create_controls(setting="expand_anomalous", label="show Friedel pairs") box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(ctrls[0], 0, wx.ALL, 5) box.Add(ctrls2[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="spheres", label="Display reflections as spheres") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) self.spheres_ctrl = ctrls[0] else: self.spheres_ctrl = oop.null() ###Kau added start # d_min control # self.d_min_ctrl = floatspin.FloatSpin(parent=self, increment=0.05, digits=2) # self.d_min_ctrl.Bind(wx.EVT_SET_FOCUS, lambda evt: None) # if (wx.VERSION >= (2,9)) : # XXX FloatSpin bug in 2.9.2/wxOSX_Cocoa # self.d_min_ctrl.SetBackgroundColour(self.GetBackgroundColour()) # box = wx.BoxSizer(wx.HORIZONTAL) # self.panel_sizer.Add(box) # label = wx.StaticText(self,-1,"High resolution:") # box.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # box.Add(self.d_min_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # self.Bind(floatspin.EVT_FLOATSPIN, self.OnChangeResolution, self.d_min_ctrl) ##kau added end box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) txt = wx.StaticText(self.panel, -1, "Color scheme:") box.Add(txt, 0, wx.TOP | wx.BOTTOM | wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) self.color_ctrl = wx.Choice(self.panel, -1, choices=[ "rainbow", "heatmap", "redblue", "grayscale", "monochrome" ]) self.color_ctrl.SetStringSelection(self.settings.color_scheme) box.Add(self.color_ctrl, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_CHOICE, self.OnChangeColor, self.color_ctrl) ctrls = self.create_controls(setting="show_missing", label="Show missing reflections") ctrls2 = self.create_controls(setting="show_only_missing", label="only") box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(ctrls[0], 0, wx.ALL, 5) box.Add(ctrls2[0], 0, wx.ALL, 5) ctrls = self.create_controls(setting="show_systematic_absences", label="Show systematic absences") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) if (self.is_3d_view): ctrls = self.create_controls(setting="sphere_detail", label="Sphere detail level", min=4, max=20) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(ctrls[0], 0, wx.TOP | wx.BOTTOM | wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) box.Add(ctrls[1], 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.panel_sizer.Add(box) ctrls = self.create_controls( setting="slice_mode", label="Show only a slice through reciprocal space") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) self.slice_ctrl = ctrls[0] ctrls = self.create_controls( setting="keep_constant_scale", label="Keep scale constant across all slices") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) box2 = wx.BoxSizer(wx.HORIZONTAL) box2.Add(wx.StaticText(self.panel, -1, "View slice:"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) ctrls = self.create_controls self.hkl_choice = wx.Choice(self.panel, -1, choices=["h", "k", "l"]) self.hkl_choice.SetStringSelection(self.settings.slice_axis) box2.Add(self.hkl_choice, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) box2.Add(wx.StaticText(self.panel, -1, "="), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.slice_index = wx.SpinCtrl(self.panel, -1) self.slice_index.SetValue(self.settings.slice_index) box2.Add(self.slice_index, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.panel_sizer.Add(box2) self.Bind(wx.EVT_CHOICE, self.OnSetSlice, self.hkl_choice) self.Bind(wx.EVT_SPINCTRL, self.OnSetSlice, self.slice_index) # reflection info box box = wx.StaticBox(self.panel, -1, "Reflection info") box_szr = wx.StaticBoxSizer(box, wx.VERTICAL) self.panel_sizer.Add((1, 10)) self.panel_sizer.Add(box_szr, 0, wx.EXPAND | wx.ALL) grid_szr = wx.FlexGridSizer(rows=3, cols=2) box_szr.Add(grid_szr, 0, wx.EXPAND | wx.ALL) grid_szr.Add(wx.StaticText(self.panel, -1, "Clicked:"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.hkl_info = wx.TextCtrl(self.panel, -1, size=(80, -1), style=wx.TE_READONLY) grid_szr.Add(self.hkl_info, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) grid_szr.Add(wx.StaticText(self.panel, -1, "Resolution:"), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.d_min_info = wx.TextCtrl(self.panel, -1, size=(80, -1), style=wx.TE_READONLY) grid_szr.Add(self.d_min_info, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.add_value_widgets(grid_szr)
def add_controls (self) : self._index_span = None self._last_sg_sel = None # d_min control self.d_min_ctrl = floatspin.FloatSpin(parent=self, increment=0.05, digits=2) self.d_min_ctrl.Bind(wx.EVT_SET_FOCUS, lambda evt: None) if (wx.VERSION >= (2,9)) : # XXX FloatSpin bug in 2.9.2/wxOSX_Cocoa self.d_min_ctrl.SetBackgroundColour(self.GetBackgroundColour()) box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) label = wx.StaticText(self,-1,"High resolution:") box.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) box.Add(self.d_min_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(floatspin.EVT_FLOATSPIN, self.OnChangeResolution, self.d_min_ctrl) # scale control box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) label = wx.StaticText(self, -1, "Scale:") box.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.scale_ctrl = wx.Slider(self, size=(120,-1), style=wx.SL_AUTOTICKS) self.scale_ctrl.SetMin(0) self.scale_ctrl.SetMax(16) self.scale_ctrl.SetTickFreq(4, 1) self.Bind(wx.EVT_SLIDER, self.OnSetScale, self.scale_ctrl) for x in [0, 4, 8, 12, 16] : self.scale_ctrl.SetTick(x) self.scale_ctrl.SetValue((self.settings.scale * 4) - 4) box.Add(self.scale_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) # ctrls = self.create_controls( setting="black_background", label="Black background") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="show_axes", label="Show h,k,l axes") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="show_data_over_sigma", label="Use I or F over sigma") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) if (not self.is_3d_view) : ctrls = self.create_controls( setting="uniform_size", label="Use same radius for all points") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="sqrt_scale_radii", label="Scale radii to sqrt(value)") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="sqrt_scale_colors", label="Scale colors to sqrt(value)") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) self.sg_ctrl = oop.null() if (self.is_3d_view) : self.sg_ctrl = wx.Choice(self.panel, -1, choices=[], size=(160,-1)) self.Bind(wx.EVT_CHOICE, self.OnChangeSpaceGroup, self.sg_ctrl) box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(wx.StaticText(self.panel, -1, "Space group:"), 0, wx.ALL, 5) box.Add(self.sg_ctrl, 0, wx.ALL, 5) ctrls = self.create_controls( setting="expand_to_p1", label="Expand data to P1") ctrls2 = self.create_controls( setting="expand_anomalous", label="show Friedel pairs") box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(ctrls[0], 0, wx.ALL, 5) box.Add(ctrls2[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="spheres", label="Display reflections as spheres") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) self.spheres_ctrl = ctrls[0] else : self.spheres_ctrl = oop.null() box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) txt = wx.StaticText(self.panel, -1, "Color scheme:") box.Add(txt, 0, wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) self.color_ctrl = wx.Choice(self.panel, -1, choices=["rainbow","heatmap","redblue","grayscale","monochrome"]) self.color_ctrl.SetStringSelection(self.settings.color_scheme) box.Add(self.color_ctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.Bind(wx.EVT_CHOICE, self.OnChangeColor, self.color_ctrl) ctrls = self.create_controls( setting="show_missing", label="Show missing reflections") ctrls2 = self.create_controls( setting="show_only_missing", label="only") box = wx.BoxSizer(wx.HORIZONTAL) self.panel_sizer.Add(box) box.Add(ctrls[0], 0, wx.ALL, 5) box.Add(ctrls2[0], 0, wx.ALL, 5) ctrls = self.create_controls( setting="show_systematic_absences", label="Show systematic absences") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) if (self.is_3d_view) : ctrls = self.create_controls( setting="sphere_detail", label="Sphere detail level", min=4, max=20) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(ctrls[0], 0, wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) box.Add(ctrls[1], 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.panel_sizer.Add(box) ctrls = self.create_controls( setting="slice_mode", label="Show only a slice through reciprocal space") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) self.slice_ctrl = ctrls[0] ctrls = self.create_controls( setting="keep_constant_scale", label="Keep scale constant across all slices") self.panel_sizer.Add(ctrls[0], 0, wx.ALL, 5) box2 = wx.BoxSizer(wx.HORIZONTAL) box2.Add(wx.StaticText(self.panel, -1, "View slice:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) ctrls = self.create_controls self.hkl_choice = wx.Choice(self.panel, -1, choices=["h","k","l"]) self.hkl_choice.SetStringSelection(self.settings.slice_axis) box2.Add(self.hkl_choice, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) box2.Add(wx.StaticText(self.panel, -1, "="), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.slice_index = wx.SpinCtrl(self.panel, -1) self.slice_index.SetValue(self.settings.slice_index) box2.Add(self.slice_index, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.panel_sizer.Add(box2) self.Bind(wx.EVT_CHOICE, self.OnSetSlice, self.hkl_choice) self.Bind(wx.EVT_SPINCTRL, self.OnSetSlice, self.slice_index) # reflection info box box = wx.StaticBox(self.panel, -1, "Reflection info") box_szr = wx.StaticBoxSizer(box, wx.VERTICAL) self.panel_sizer.Add((1,10)) self.panel_sizer.Add(box_szr, 0, wx.EXPAND|wx.ALL) grid_szr = wx.FlexGridSizer(rows=3, cols=2) box_szr.Add(grid_szr, 0, wx.EXPAND|wx.ALL) grid_szr.Add(wx.StaticText(self.panel, -1, "Clicked:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.hkl_info = wx.TextCtrl(self.panel, -1, size=(80,-1), style=wx.TE_READONLY) grid_szr.Add(self.hkl_info, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) grid_szr.Add(wx.StaticText(self.panel, -1, "Resolution:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.d_min_info = wx.TextCtrl(self.panel, -1, size=(80,-1), style=wx.TE_READONLY) grid_szr.Add(self.d_min_info, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) self.add_value_widgets(grid_szr)
def process_input_array(self, arr): array = arr.deep_copy() work_array = arr multiplicities = None try: if self.merge_equivalents: array, multiplicities, merge = MergeData( array, self.settings.show_anomalous_pairs) settings = self.settings data = array.data() #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) self.missing_set = oop.null() #if (array.is_xray_intensity_array()): # data.set_selected(data < 0, flex.double(data.size(), 0.)) if (array.is_unique_set_under_symmetry()) and ( settings.map_to_asu): array = array.map_to_asu() if (multiplicities is not None): multiplicities = multiplicities.map_to_asu() if (settings.d_min is not None): array = array.resolution_filter(d_min=settings.d_min) if (multiplicities is not None): multiplicities = multiplicities.resolution_filter( d_min=settings.d_min) self.filtered_array = array.deep_copy() if (settings.expand_anomalous): if not array.is_unique_set_under_symmetry(): raise Sorry( "Error! Cannot generate bijvoet mates of unmerged reflections." ) array = array.generate_bijvoet_mates() original_symmetry = array.crystal_symmetry() if (multiplicities is not None): multiplicities = multiplicities.generate_bijvoet_mates() if (self.settings.show_missing): self.missing_set = array.complete_set().lone_set(array) if self.settings.show_anomalous_pairs: self.missing_set = self.missing_set.select( self.missing_set.centric_flags().data(), negate=True) if (settings.expand_to_p1): if not array.is_unique_set_under_symmetry(): raise Sorry( "Error! Cannot expand unmerged reflections to P1.") original_symmetry = array.crystal_symmetry() array = array.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) #array = array.niggli_cell().expand_to_p1() #self.missing_set = self.missing_set.niggli_cell().expand_to_p1() self.missing_set = self.missing_set.expand_to_p1( ).customized_copy(crystal_symmetry=original_symmetry) if (multiplicities is not None): multiplicities = multiplicities.expand_to_p1( ).customized_copy(crystal_symmetry=original_symmetry) data = array.data() self.r_free_mode = False self.phases = flex.double(data.size(), float('nan')) self.radians = flex.double(data.size(), float('nan')) self.ampl = flex.double(data.size(), float('nan')) self.sigmas = None if isinstance(data, flex.bool): self.r_free_mode = True data_as_float = flex.double(data.size(), 0.0) data_as_float.set_selected(data == True, flex.double(data.size(), 1.0)) data = data_as_float self.data = data #.deep_copy() else: if isinstance(data, flex.double): self.data = data #.deep_copy() elif isinstance(data, flex.complex_double): self.data = data #.deep_copy() self.ampl = flex.abs(data) self.phases = flex.arg(data) * 180.0 / math.pi # purge nan values from array to avoid crash in fmod_positive() #b = flex.bool([bool(math.isnan(e)) for e in self.phases]) b = graphics_utils.IsNansArray(self.phases) # replace the nan values with an arbitrary float value self.phases = self.phases.set_selected(b, 42.4242) # Cast negative degrees to equivalent positive degrees self.phases = flex.fmod_positive(self.phases, 360.0) self.radians = flex.arg(data) # replace the nan values with an arbitrary float value self.radians = self.radians.set_selected(b, 0.424242) elif hasattr(array.data(), "as_double"): self.data = data else: raise RuntimeError("Unexpected data type: %r" % data) if (settings.show_data_over_sigma): if (array.sigmas() is None): raise Sorry("sigmas not defined.") sigmas = array.sigmas() non_zero_sel = sigmas != 0 array = array.select(non_zero_sel) array = array.customized_copy(data=array.data() / array.sigmas()) self.data = array.data() if (multiplicities is not None): multiplicities = multiplicities.select(non_zero_sel) if array.sigmas() is not None: self.sigmas = array.sigmas() else: self.sigmas = None work_array = array except Exception as e: print(to_str(e) + "".join(traceback.format_stack(limit=10))) raise e return None, None work_array.set_info(arr.info()) multiplicities = multiplicities return work_array, multiplicities
def exercise_floating_origin_restraints(self): n = self.n_independent_params eps_zero_rhs = 1e-6 connectivity_table = smtbx.utils.connectivity_table(self.xray_structure) reparametrisation = constraints.reparametrisation( structure=self.xray_structure, constraints=[], connectivity_table=connectivity_table) obs = self.fo_sq.as_xray_observations() ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type=oop.null()) ls.build_up() unrestrained_normal_matrix = ls.normal_matrix_packed_u() assert len(unrestrained_normal_matrix) == n*(n+1)//2 ev = eigensystem.real_symmetric( unrestrained_normal_matrix.matrix_packed_u_as_symmetric()) unrestrained_eigenval = ev.values() unrestrained_eigenvec = ev.vectors() ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.homogeneous_weighting) ls.build_up() # Let's check that the computed singular directions span the same # space as the expected ones singular_test = flex.double() jac = ls.reparametrisation.jacobian_transpose_matching_grad_fc() m = 0 for s in ls.origin_fixing_restraint.singular_directions: assert s.norm() != 0 singular_test.extend(jac*s) m += 1 for s in self.continuous_origin_shift_basis: singular_test.extend(flex.double(s)) m += 1 singular_test.reshape(flex.grid(m, n)) assert self.rank(singular_test) == len(self.continuous_origin_shift_basis) assert ls.opposite_of_gradient()\ .all_approx_equal(0, eps_zero_rhs),\ list(ls.gradient()) restrained_normal_matrix = ls.normal_matrix_packed_u() assert len(restrained_normal_matrix) == n*(n+1)//2 ev = eigensystem.real_symmetric( restrained_normal_matrix.matrix_packed_u_as_symmetric()) restrained_eigenval = ev.values() restrained_eigenvec = ev.vectors() # The eigendecomposition of the normal matrix # for the unrestrained problem is: # A = sum_{0 <= i < n-p-1} lambda_i v_i^T v_i # where the eigenvalues lambda_i are sorted in decreasing order # and p is the dimension of the continous origin shift space. # In particular A v_i = 0, n-p <= i < n. # In the restrained case, it becomes: # A' = A + sum_{n-p <= i < n} mu v_i^T v_i p = len(self.continuous_origin_shift_basis) assert approx_equal(restrained_eigenval[p:], unrestrained_eigenval[:-p], eps=1e-12) assert unrestrained_eigenval[-p]/unrestrained_eigenval[-p-1] < 1e-12 if p > 1: # eigenvectors are stored by rows unrestrained_null_space = unrestrained_eigenvec.matrix_copy_block( i_row=n-p, i_column=0, n_rows=p, n_columns=n) assert self.rank(unrestrained_null_space) == p restrained_space = restrained_eigenvec.matrix_copy_block( i_row=0, i_column=0, n_rows=p, n_columns=n) assert self.rank(restrained_space) == p singular = flex.double( self.continuous_origin_shift_basis) assert self.rank(singular) == p rank_finder = flex.double(n*3*p) rank_finder.resize(flex.grid(3*p, n)) rank_finder.matrix_paste_block_in_place(unrestrained_null_space, i_row=0, i_column=0) rank_finder.matrix_paste_block_in_place(restrained_space, i_row=p, i_column=0) rank_finder.matrix_paste_block_in_place(singular, i_row=2*p, i_column=0) assert self.rank(rank_finder) == p else: # this branch handles the case p=1 # it's necessary to work around a bug in the svd module # ( nx1 matrices crashes the code ) assert approx_equal( restrained_eigenvec[0:n].angle( unrestrained_eigenvec[-n:]) % math.pi, 0) assert approx_equal( unrestrained_eigenvec[-n:].angle( flex.double(self.continuous_origin_shift_basis[0])) % math.pi, 0) # Do the floating origin restraints prevent the structure from floating? xs = self.xray_structure.deep_copy_scatterers() ls = least_squares.crystallographic_ls( obs, reparametrisation, weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting ) barycentre_0 = xs.sites_frac().mean() while 1: xs.shake_sites_in_place(rms_difference=0.15) xs.apply_symmetry_sites() barycentre_1 = xs.sites_frac().mean() delta = matrix.col(barycentre_1) - matrix.col(barycentre_0) moved_far_enough = 0 for singular in self.continuous_origin_shift_basis: e = matrix.col(singular[:3]) if not approx_equal(delta.dot(e), 0, eps=0.01, out=None): moved_far_enough += 1 if moved_far_enough: break # one refinement cycle ls.build_up() ls.solve() shifts = ls.step() # That's what floating origin restraints are for! # Note that in the presence of special position, that's different # from the barycentre not moving along the continuous shift directions. # TODO: typeset notes about that subtlety. for singular in self.continuous_origin_shift_basis: assert approx_equal(shifts.dot(flex.double(singular)), 0, eps=1e-12)
def process_input_array (self) : from cctbx.array_family import flex array = self.miller_array.deep_copy() multiplicities = None if self.merge_equivalents : if self.settings.show_anomalous_pairs: from cctbx import miller merge = array.merge_equivalents() multiplicities = merge.redundancies() asu, matches = multiplicities.match_bijvoet_mates() mult_plus, mult_minus = multiplicities.hemispheres_acentrics() anom_mult = flex.int( min(p, m) for (p, m) in zip(mult_plus.data(), mult_minus.data())) #flex.min_max_mean_double(anom_mult.as_double()).show() anomalous_multiplicities = miller.array( miller.set(asu.crystal_symmetry(), mult_plus.indices(), anomalous_flag=False), anom_mult) anomalous_multiplicities = anomalous_multiplicities.select( anomalous_multiplicities.data() > 0) array = anomalous_multiplicities multiplicities = anomalous_multiplicities else: merge = array.merge_equivalents() array = merge.array() multiplicities = merge.redundancies() settings = self.settings data = array.data() self.missing_set = oop.null() if (array.is_xray_intensity_array()) : data.set_selected(data < 0, flex.double(data.size(), 0.)) if (array.is_unique_set_under_symmetry()) and (settings.map_to_asu) : array = array.map_to_asu() if (multiplicities is not None) : multiplicities = multiplicities.map_to_asu() if (settings.d_min is not None) : array = array.resolution_filter(d_min=settings.d_min) if (multiplicities is not None) : multiplicities = multiplicities.resolution_filter( d_min=settings.d_min) self.filtered_array = array.deep_copy() if (settings.expand_anomalous) : array = array.generate_bijvoet_mates() if (multiplicities is not None) : multiplicities = multiplicities.generate_bijvoet_mates() if (self.settings.show_missing) : self.missing_set = array.complete_set().lone_set(array) if self.settings.show_anomalous_pairs: self.missing_set = self.missing_set.select( self.missing_set.centric_flags().data(), negate=True) if (settings.expand_to_p1) : original_symmetry = array.crystal_symmetry() array = array.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) #array = array.niggli_cell().expand_to_p1() #self.missing_set = self.missing_set.niggli_cell().expand_to_p1() self.missing_set = self.missing_set.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) if (multiplicities is not None) : multiplicities = multiplicities.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) data = array.data() self.r_free_mode = False if isinstance(data, flex.bool) : self.r_free_mode = True data_as_float = flex.double(data.size(), 0.0) data_as_float.set_selected(data==True, flex.double(data.size(), 1.0)) data = data_as_float self.data = data.deep_copy() else : if isinstance(data, flex.double) : self.data = data.deep_copy() elif isinstance(data, flex.complex_double) : self.data = flex.abs(data) elif hasattr(array.data(), "as_double") : self.data = array.data().as_double() else: raise RuntimeError("Unexpected data type: %r" % data) if (settings.show_data_over_sigma) : if (array.sigmas() is None) : raise Sorry("sigmas not defined.") sigmas = array.sigmas() non_zero_sel = sigmas != 0 array = array.select(non_zero_sel) array = array.customized_copy(data=array.data()/array.sigmas()) self.data = array.data() if (multiplicities is not None) : multiplicities = multiplicities.select(non_zero_sel) self.work_array = array self.multiplicities = multiplicities
def process_input_array(self): from cctbx.array_family import flex array = self.miller_array.deep_copy() multiplicities = None if self.merge_equivalents: if self.settings.show_anomalous_pairs: from cctbx import miller merge = array.merge_equivalents() multiplicities = merge.redundancies() asu, matches = multiplicities.match_bijvoet_mates() mult_plus, mult_minus = multiplicities.hemispheres_acentrics() anom_mult = flex.int( min(p, m) for (p, m) in zip(mult_plus.data(), mult_minus.data())) #flex.min_max_mean_double(anom_mult.as_double()).show() anomalous_multiplicities = miller.array( miller.set(asu.crystal_symmetry(), mult_plus.indices(), anomalous_flag=False), anom_mult) anomalous_multiplicities = anomalous_multiplicities.select( anomalous_multiplicities.data() > 0) array = anomalous_multiplicities multiplicities = anomalous_multiplicities else: merge = array.merge_equivalents() array = merge.array() multiplicities = merge.redundancies() settings = self.settings data = array.data() self.missing_set = oop.null() if (array.is_xray_intensity_array()): data.set_selected(data < 0, flex.double(data.size(), 0.)) if (array.is_unique_set_under_symmetry()) and (settings.map_to_asu): array = array.map_to_asu() if (multiplicities is not None): multiplicities = multiplicities.map_to_asu() if (settings.d_min is not None): array = array.resolution_filter(d_min=settings.d_min) if (multiplicities is not None): multiplicities = multiplicities.resolution_filter( d_min=settings.d_min) self.filtered_array = array.deep_copy() if (settings.expand_anomalous): array = array.generate_bijvoet_mates() if (multiplicities is not None): multiplicities = multiplicities.generate_bijvoet_mates() if (self.settings.show_missing): self.missing_set = array.complete_set().lone_set(array) if self.settings.show_anomalous_pairs: self.missing_set = self.missing_set.select( self.missing_set.centric_flags().data(), negate=True) if (settings.expand_to_p1): original_symmetry = array.crystal_symmetry() array = array.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) #array = array.niggli_cell().expand_to_p1() #self.missing_set = self.missing_set.niggli_cell().expand_to_p1() self.missing_set = self.missing_set.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) if (multiplicities is not None): multiplicities = multiplicities.expand_to_p1().customized_copy( crystal_symmetry=original_symmetry) data = array.data() self.r_free_mode = False if isinstance(data, flex.bool): self.r_free_mode = True data_as_float = flex.double(data.size(), 0.0) data_as_float.set_selected(data == True, flex.double(data.size(), 1.0)) data = data_as_float self.data = data.deep_copy() else: if isinstance(data, flex.double): self.data = data.deep_copy() elif isinstance(data, flex.complex_double): self.data = flex.abs(data) elif hasattr(array.data(), "as_double"): self.data = array.data().as_double() else: raise RuntimeError("Unexpected data type: %r" % data) if (settings.show_data_over_sigma): if (array.sigmas() is None): raise Sorry("sigmas not defined.") sigmas = array.sigmas() non_zero_sel = sigmas != 0 array = array.select(non_zero_sel) array = array.customized_copy(data=array.data() / array.sigmas()) self.data = array.data() if (multiplicities is not None): multiplicities = multiplicities.select(non_zero_sel) self.work_array = array self.multiplicities = multiplicities
def __init__(self, parent, figure_size=(8, 6), font_size=12, title_font_size=10, facecolor='white', transparent=False, handle_left_click=False, show_data_points=True, point_types=('o', '^', '+', 's', 'D'), title_alignment="right"): wx.BoxSizer.__init__(self, wx.VERTICAL) adopt_init_args(self, locals()) self._fonts = {} self.disabled = False try: import matplotlib from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg from matplotlib.backends.backend_wxagg import FigureManager import matplotlib.ticker import matplotlib.cm import matplotlib.figure import matplotlib.font_manager except ImportError as e: print("") print("Error loading matplotlib module:") print(e) print("") self.disabled = True self.canvas = oop.null() self.figure = oop.null() self.text_font = oop.null() self.p = oop.null() w = int(figure_size[0] * 72) h = int(figure_size[1] * 72) panel = wx.Panel(parent=parent, size=(w, h)) panel.SetBackgroundColour((150, 150, 150)) szr = wx.BoxSizer(wx.VERTICAL) panel.SetSizer(szr) txt = wx.StaticText( parent=panel, label="Plotting disabled due to missing libraries.") szr.Add(txt, 1, wx.ALL | wx.ALIGN_CENTER, 10) txt.SetForegroundColour((255, 0, 0)) font = txt.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) txt.SetFont(font) txt2 = wx.StaticText(parent=panel, label="Original error:") txt2.SetForegroundColour((255, 0, 0)) szr.Add(txt2, 1, wx.ALL | wx.ALIGN_CENTER, 10) txt3 = wx.StaticText(parent=panel, label=str(e)) txt3.SetForegroundColour((255, 0, 0)) szr.Add(txt3, 1, wx.ALL | wx.ALIGN_CENTER, 10) self.Add(panel, 1, wx.EXPAND | wx.ALL) self.null_fmt = oop.null() else: self.figure = matplotlib.figure.Figure(figure_size, 72, linewidth=0, facecolor=facecolor) if transparent: self.figure.figurePatch.set_alpha(0.0) self.canvas = FigureCanvasWxAgg(self.parent, -1, self.figure) self.canvas.toolbar = oop.null() self.figmgr = FigureManager(self.canvas, 1, self) self.Add(self.canvas, 1, wx.EXPAND | wx.ALL) self.setup_fonts() self.null_fmt = matplotlib.ticker.NullFormatter() if self.handle_left_click: self.canvas.mpl_connect("button_release_event", self.OnClick) else: self.canvas.Bind(wx.EVT_CONTEXT_MENU, self.OnRightClick, self.canvas) if (wx.Platform == '__WXMAC__'): # FIXME MSW okay, check GTK self.canvas.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel, self.canvas)