def exercise(): g = graphics_utils.make_rainbow_gradient(nbins=21) assert approx_equal(g[0], (0.0, 0.0, 1.0)) assert approx_equal(g[10], (0.0, 1.0, 0.0)) assert approx_equal(g[-1], (1.0, 0.0, 0.0)) sel = flex.bool([True] * 10) sel[5] = False r = graphics_utils.color_rainbow( selection=sel, color_all=False) assert approx_equal(r[0], (0.0,0.0,1.0)) assert approx_equal(r[-1], (1.0,0.0,0.0)) assert approx_equal(r[4], (0.0,1.0,0.0)) r2 = graphics_utils.color_rainbow( selection=sel, color_all=True) assert approx_equal(r2[0], (0.0,0.0,1.0)) assert approx_equal(r2[-1], (1.0,0.0,0.0)) assert approx_equal(r2[6], (2/3.,1.0,0.0)) b = flex.double([4.0,5.2,1.7,6.9,9.5,24.3]) c = graphics_utils.color_by_property( properties=b, selection=flex.bool(b.size(), True)) assert approx_equal(c[2], (0.0,0.0,1.0)) c2 = graphics_utils.scale_selected_colors( input_colors=c, selection=flex.bool(c.size(), True), scale=0.9) assert approx_equal(c2[2], (0.0,0.0,0.9)) c3 = graphics_utils.grayscale_by_property( properties=b, selection=flex.bool(b.size(), True)) assert approx_equal(c3[2], (0.95,0.95,0.95))
def exercise () : g = graphics_utils.make_rainbow_gradient(nbins=21) assert approx_equal(g[0], (0.0, 0.0, 1.0)) assert approx_equal(g[10], (0.0, 1.0, 0.0)) assert approx_equal(g[-1], (1.0, 0.0, 0.0)) sel = flex.bool([True] * 10) sel[5] = False r = graphics_utils.color_rainbow( selection=sel, color_all=False) assert approx_equal(r[0], (0.0,0.0,1.0)) assert approx_equal(r[-1], (1.0,0.0,0.0)) assert approx_equal(r[4], (0.0,1.0,0.0)) r2 = graphics_utils.color_rainbow( selection=sel, color_all=True) assert approx_equal(r2[0], (0.0,0.0,1.0)) assert approx_equal(r2[-1], (1.0,0.0,0.0)) assert approx_equal(r2[6], (2/3.,1.0,0.0)) b = flex.double([4.0,5.2,1.7,6.9,9.5,24.3]) c = graphics_utils.color_by_property( properties=b, selection=flex.bool(b.size(), True)) assert approx_equal(c[2], (0.0,0.0,1.0)) c2 = graphics_utils.scale_selected_colors( input_colors=c, selection=flex.bool(c.size(), True), scale=0.9) assert approx_equal(c2[2], (0.0,0.0,0.9)) c3 = graphics_utils.grayscale_by_property( properties=b, selection=flex.bool(b.size(), True)) assert approx_equal(c3[2], (0.95,0.95,0.95))
def color_b (self) : cached = self._color_cache.get("b") if cached is not None : self.atom_colors = cached else : from scitbx import graphics_utils self.atom_colors = graphics_utils.color_by_property( properties=self.atoms.extract_b(), selection=self.visibility.atoms_visible, color_all=False, gradient_type="rainbow") self._color_cache["b"] = self.atom_colors
def generate_view_data(self): from scitbx.array_family import flex from scitbx import graphics_utils settings = self.settings data_for_colors = data_for_radii = None data = self.data #self.work_array.data() sigmas = self.sigmas if (isinstance(data, flex.double) and data.all_eq(0)): data = flex.double(data.size(), 1) if ((self.multiplicities is not None) and (settings.scale_colors_multiplicity)): data_for_colors = self.multiplicities.data().as_double() assert data_for_colors.size() == data.size() elif (settings.sqrt_scale_colors) and (isinstance(data, flex.double)): data_for_colors = flex.sqrt(flex.abs(data)) elif isinstance(data, flex.complex_double): data_for_colors = self.radians # when using map coefficients the sigmas are filled with foms if provided #if self.sigmas: # self.foms = self.sigmas foms_for_colours = self.foms elif (settings.sigma_color) and sigmas is not None: data_for_colors = sigmas.as_double() else: data_for_colors = flex.abs(data.deep_copy()) uc = self.work_array.unit_cell() #abc = uc.parameters()[0:3] min_dist = min(uc.reciprocal_space_vector((1, 1, 1))) min_radius = 0.20 * min_dist max_radius = 40 * min_dist if ((self.multiplicities is not None) and (settings.scale_radii_multiplicity)): #data_for_radii = data.deep_copy() data_for_radii = self.multiplicities.data().as_double() if (settings.sigma_radius) and sigmas is not None: data_for_radii = sigmas * self.multiplicities.as_double() #print "sigmas: " + self.miller_array.info().label_string() assert data_for_radii.size() == data.size() #elif (settings.sqrt_scale_radii) and (isinstance(data, flex.double)): # data_for_radii = flex.sqrt(flex.abs(data)) elif (settings.sigma_radius) and sigmas is not None: data_for_radii = sigmas.as_double() #print "sigmas: " + self.miller_array.info().label_string() else: #data_for_radii = flex.abs(data.deep_copy()) data_for_radii = nth_power_scale(data.deep_copy(), settings.nth_power_scale_radii) if (settings.slice_mode): data = data.select(self.slice_selection) if (not settings.keep_constant_scale): data_for_radii = data_for_radii.select(self.slice_selection) data_for_colors = data_for_colors.select(self.slice_selection) foms_for_colours = foms_for_colours.select( self.slice_selection) if isinstance(data, flex.complex_double): if len([e for e in foms_for_colours if math.isnan(e)]) > 0: colors = graphics_utils.colour_by_phi_FOM( data_for_colors, None) else: colors = graphics_utils.colour_by_phi_FOM( data_for_colors, foms_for_colours) elif (settings.color_scheme in ["rainbow", "heatmap", "redblue"]): colors = graphics_utils.color_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), color_all=False, gradient_type=settings.color_scheme) elif (settings.color_scheme == "grayscale"): colors = graphics_utils.grayscale_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), shade_all=False, invert=settings.black_background) else: if (settings.black_background): base_color = (1.0, 1.0, 1.0) else: base_color = (0.0, 0.0, 0.0) colors = flex.vec3_double(data_for_colors.size(), base_color) if (settings.slice_mode) and (settings.keep_constant_scale): colors = colors.select(self.slice_selection) data_for_radii = data_for_radii.select(self.slice_selection) #if (settings.sqrt_scale_radii) and (not settings.scale_radii_multiplicity): # data_for_radii = flex.sqrt(flex.abs(data_for_radii)) if len(data_for_radii): max_value = flex.max(data_for_radii) scale = max_radius / max_value radii = data_for_radii * (scale * self.settings.scale) too_small = radii < min_radius if (too_small.count(True) > 0): radii.set_selected(too_small, flex.double(radii.size(), min_radius)) assert radii.size() == colors.size() else: radii = flex.double() max_radius = 0 self.radii = radii self.max_radius = max_radius self.colors = colors if isinstance(data, flex.complex_double): self.foms = foms_for_colours
def generate_view_data(self): from scitbx.array_family import flex #from scitbx import graphics_utils settings = self.settings data_for_colors = data_for_radii = None if not self.fullprocessarray: return data = self.data #self.work_array.data() sigmas = self.sigmas if (isinstance(data, flex.double) and data.all_eq(0)): data = flex.double(data.size(), 1) if ((self.multiplicities is not None) and (settings.scale_colors_multiplicity)): data_for_colors = self.multiplicities.data().as_double() assert data_for_colors.size() == data.size() elif (settings.sqrt_scale_colors) and (isinstance(data, flex.double)): data_for_colors = flex.sqrt(flex.abs(data)) elif isinstance(data, flex.complex_double): data_for_colors = self.radians foms_for_colours = self.foms # assuming last part of the labels indicates the phase label as in ["FCALC","PHICALC"] self.colourlabel = self.miller_array.info().labels[-1] elif (settings.sigma_color) and sigmas is not None: data_for_colors = sigmas.as_double() self.colourlabel = self.miller_array.info().labels[-1] else: data_for_colors = flex.abs(data.deep_copy()) uc = self.work_array.unit_cell() self.min_dist = min(uc.reciprocal_space_vector( (1, 1, 1))) * self.renderscale min_radius = 0.05 * self.min_dist max_radius = 0.5 * self.min_dist if ((self.multiplicities is not None) and (settings.scale_radii_multiplicity)): data_for_radii = self.multiplicities.data().as_double() if (settings.sigma_radius) and sigmas is not None: data_for_radii = sigmas * self.multiplicities.as_double() assert data_for_radii.size() == data.size() elif (settings.sigma_radius) and sigmas is not None: data_for_radii = sigmas.as_double() else: data_for_radii, self.nth_power_scale_radii = nth_power_scale( flex.abs(data.deep_copy()), settings.nth_power_scale_radii) if (settings.slice_mode): data = data.select(self.slice_selection) if (not settings.keep_constant_scale): data_for_radii = data_for_radii.select(self.slice_selection) data_for_colors = data_for_colors.select(self.slice_selection) foms_for_colours = foms_for_colours.select( self.slice_selection) if isinstance(data, flex.complex_double): if self.isUsingFOMs(): colors = graphics_utils.colour_by_phi_FOM( data_for_colors, foms_for_colours) else: colors = graphics_utils.colour_by_phi_FOM( data_for_colors, None) elif (settings.color_scheme in ["rainbow", "heatmap", "redblue"]): colors = graphics_utils.color_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), color_all=False, gradient_type=settings.color_scheme) elif (settings.color_scheme == "grayscale"): colors = graphics_utils.grayscale_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), shade_all=False, invert=settings.black_background) else: if (settings.black_background): base_color = (1.0, 1.0, 1.0) else: base_color = (0.0, 0.0, 0.0) colors = flex.vec3_double(data_for_colors.size(), base_color) if (settings.slice_mode) and (settings.keep_constant_scale): colors = colors.select(self.slice_selection) data_for_radii = data_for_radii.select(self.slice_selection) #if (settings.sqrt_scale_radii) and (not settings.scale_radii_multiplicity): # data_for_radii = flex.sqrt(flex.abs(data_for_radii)) if len(data_for_radii): #dat2 = flex.abs(flex.double([e for e in data_for_radii if not math.isnan(e)])) dat2 = flex.abs( flex.double(graphics_utils.NoNansArray(data_for_radii, 0.1))) # don't divide by 0 if dealing with selection of Rfree array where all values happen to be zero scale = max_radius / (flex.max(dat2) + 0.001) radii = data_for_radii * (self.settings.scale * scale) assert radii.size() == colors.size() else: radii = flex.double() max_radius = 0 self.radii = radii self.max_radius = max_radius self.min_radius = min_radius self.colors = colors if isinstance(data, flex.complex_double): self.foms = foms_for_colours
def render(self, canvas): from scitbx.array_family import flex from libtbx.utils import frange import math size = self.GetSize() border = 10 i_rows = flex.double_range(border, size[1] - border) scene = self.scene if self.scene.settings.scale_colors_multiplicity: data = self.scene.multiplicities.data() else: data = self.scene.data if self.settings.sqrt_scale_colors: data = flex.sqrt(data) min_data = flex.min(data) max_data = flex.max(data) data_for_colors = flex.double( frange(max_data, min_data, -(max_data - min_data) / len(i_rows))) tick_step = int(math.ceil((max_data - min_data) / 10)) i_row_ticks = [] tick_text = [] start_tick = math.floor(max_data) i_tick = 0 for i in range(len(data_for_colors) - 1): tick_d = start_tick - tick_step * i_tick if abs(data_for_colors[i] - tick_d) < abs(data_for_colors[i + 1] - tick_d): i_row_ticks.append(i_rows[i]) tick_text.append(str(int(tick_d))) i_tick += 1 tick_d = start_tick - tick_step * i_tick if tick_d == min_data: i_row_ticks.append(i_rows[-1]) tick_text.append(str(int(tick_d))) from scitbx import graphics_utils if (self.settings.color_scheme in ["rainbow", "heatmap", "redblue"]): colors = graphics_utils.color_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), color_all=False, gradient_type=self.settings.color_scheme) elif (self.settings.color_scheme == "grayscale"): colors = graphics_utils.grayscale_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), shade_all=False, invert=self.settings.black_background) else: if (self.settings.black_background): base_color = (1.0, 1.0, 1.0) else: base_color = (0.0, 0.0, 0.0) colors = flex.vec3_double(data_for_colors.size(), base_color) l_padding = border r_padding = 4 * border for i_row, color in zip(i_rows, colors): self.draw_line(canvas, l_padding, i_row, size[0] - r_padding, i_row, color=color) for i_row, text in zip(i_row_ticks, tick_text): self.draw_text(canvas, text, size[0] - 0.8 * r_padding, i_row - 5) self.draw_line(canvas, size[0] - r_padding - 10, i_row, size[0] - r_padding, i_row)
def generate_view_data(self): from scitbx.array_family import flex from scitbx import graphics_utils settings = self.settings data_for_colors = data_for_radii = None data = self.data #self.work_array.data() if (isinstance(data, flex.double) and data.all_eq(0)): data = flex.double(data.size(), 1) if ((self.multiplicities is not None) and (settings.scale_colors_multiplicity)): data_for_colors = self.multiplicities.data().as_double() assert data_for_colors.size() == data.size() elif (settings.sqrt_scale_colors) and (isinstance(data, flex.double)): data_for_colors = flex.sqrt(data) else: data_for_colors = data.deep_copy() if ((self.multiplicities is not None) and (settings.scale_radii_multiplicity)): #data_for_radii = data.deep_copy() data_for_radii = self.multiplicities.data().as_double() assert data_for_radii.size() == data.size() elif (settings.sqrt_scale_radii) and (isinstance(data, flex.double)): data_for_radii = flex.sqrt(data) else: data_for_radii = data.deep_copy() if (settings.slice_mode): data = data.select(self.slice_selection) if (not settings.keep_constant_scale): data_for_radii = data_for_radii.select(self.slice_selection) data_for_colors = data_for_colors.select(self.slice_selection) if (settings.color_scheme in ["rainbow", "heatmap", "redblue"]): colors = graphics_utils.color_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), color_all=False, gradient_type=settings.color_scheme) elif (settings.color_scheme == "grayscale"): colors = graphics_utils.grayscale_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), shade_all=False, invert=settings.black_background) else: if (settings.black_background): base_color = (1.0, 1.0, 1.0) else: base_color = (0.0, 0.0, 0.0) colors = flex.vec3_double(data_for_colors.size(), base_color) if (settings.slice_mode) and (settings.keep_constant_scale): colors = colors.select(self.slice_selection) data_for_radii = data_for_radii.select(self.slice_selection) uc = self.work_array.unit_cell() abc = uc.parameters()[0:3] min_dist = min(uc.reciprocal_space_vector((1, 1, 1))) min_radius = 0.20 * min_dist max_radius = 40 * min_dist if (settings.sqrt_scale_radii) and ( not settings.scale_radii_multiplicity): data_for_radii = flex.sqrt(data_for_radii) if len(data_for_radii): max_value = flex.max(data_for_radii) scale = max_radius / max_value radii = data_for_radii * scale too_small = radii < min_radius if (too_small.count(True) > 0): radii.set_selected(too_small, flex.double(radii.size(), min_radius)) assert radii.size() == colors.size() else: radii = flex.double() max_radius = 0 self.radii = radii self.max_radius = max_radius self.colors = colors
def generate_view_data (self) : from scitbx.array_family import flex from scitbx import graphics_utils settings = self.settings data_for_colors = data_for_radii = None data = self.data #self.work_array.data() if (isinstance(data, flex.double) and data.all_eq(0)): data = flex.double(data.size(), 1) if ((self.multiplicities is not None) and (settings.scale_colors_multiplicity)) : data_for_colors = self.multiplicities.data().as_double() assert data_for_colors.size() == data.size() elif (settings.sqrt_scale_colors) and (isinstance(data, flex.double)) : data_for_colors = flex.sqrt(data) else : data_for_colors = data.deep_copy() if ((self.multiplicities is not None) and (settings.scale_radii_multiplicity)) : #data_for_radii = data.deep_copy() data_for_radii = self.multiplicities.data().as_double() assert data_for_radii.size() == data.size() elif (settings.sqrt_scale_radii) and (isinstance(data, flex.double)) : data_for_radii = flex.sqrt(data) else : data_for_radii = data.deep_copy() if (settings.slice_mode) : data = data.select(self.slice_selection) if (not settings.keep_constant_scale) : data_for_radii = data_for_radii.select(self.slice_selection) data_for_colors = data_for_colors.select(self.slice_selection) if (settings.color_scheme in ["rainbow", "heatmap", "redblue"]) : colors = graphics_utils.color_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), color_all=False, gradient_type=settings.color_scheme) elif (settings.color_scheme == "grayscale") : colors = graphics_utils.grayscale_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), shade_all=False, invert=settings.black_background) else : if (settings.black_background) : base_color = (1.0,1.0,1.0) else : base_color = (0.0,0.0,0.0) colors = flex.vec3_double(data_for_colors.size(), base_color) if (settings.slice_mode) and (settings.keep_constant_scale) : colors = colors.select(self.slice_selection) data_for_radii = data_for_radii.select(self.slice_selection) uc = self.work_array.unit_cell() abc = uc.parameters()[0:3] min_dist = min(uc.reciprocal_space_vector((1,1,1))) min_radius = 0.20 * min_dist max_radius = 40 * min_dist if (settings.sqrt_scale_radii) and (not settings.scale_radii_multiplicity): data_for_radii = flex.sqrt(data_for_radii) if len(data_for_radii): max_value = flex.max(data_for_radii) scale = max_radius / max_value radii = data_for_radii * scale too_small = radii < min_radius if (too_small.count(True) > 0) : radii.set_selected(too_small, flex.double(radii.size(), min_radius)) assert radii.size() == colors.size() else: radii = flex.double() max_radius = 0 self.radii = radii self.max_radius = max_radius self.colors = colors
def DrawNGLJavaScript(self): if self.miller_array is None: self.mprint("A miller array must be selected for drawing") return self.mprint("Composing NGL JavaScript...") h_axis = self.scene.axes[0] k_axis = self.scene.axes[1] l_axis = self.scene.axes[2] nrefls = self.scene.points.size() Hstararrowstart = roundoff( [-h_axis[0] * 100, -h_axis[1] * 100, -h_axis[2] * 100]) Hstararrowend = roundoff( [h_axis[0] * 100, h_axis[1] * 100, h_axis[2] * 100]) Hstararrowtxt = roundoff( [h_axis[0] * 102, h_axis[1] * 102, h_axis[2] * 102]) Kstararrowstart = roundoff( [-k_axis[0] * 100, -k_axis[1] * 100, -k_axis[2] * 100]) Kstararrowend = roundoff( [k_axis[0] * 100, k_axis[1] * 100, k_axis[2] * 100]) Kstararrowtxt = roundoff( [k_axis[0] * 102, k_axis[1] * 102, k_axis[2] * 102]) Lstararrowstart = roundoff( [-l_axis[0] * 100, -l_axis[1] * 100, -l_axis[2] * 100]) Lstararrowend = roundoff( [l_axis[0] * 100, l_axis[1] * 100, l_axis[2] * 100]) Lstararrowtxt = roundoff( [l_axis[0] * 102, l_axis[1] * 102, l_axis[2] * 102]) # make arrow font size roughly proportional to radius of highest resolution shell fontsize = str(1.0 + roundoff( math.pow(max(self.miller_array.index_span().max()), 1.0 / 3.0))) arrowstr = """ // xyz arrows shape.addSphere( [0,0,0] , [ 1, 1, 1 ], 0.3, 'Origo'); //blue-x shape.addArrow( %s, %s , [ 0, 0, 1 ], 0.1); //green-y shape.addArrow( %s, %s , [ 0, 1, 0 ], 0.1); //red-z shape.addArrow( %s, %s , [ 1, 0, 0 ], 0.1); shape.addText( %s, [ 0, 0, 1 ], %s, 'h'); shape.addText( %s, [ 0, 1, 0 ], %s, 'k'); shape.addText( %s, [ 1, 0, 0 ], %s, 'l'); """ % (str(Hstararrowstart), str(Hstararrowend), str(Kstararrowstart), str(Kstararrowend), str(Lstararrowstart), str(Lstararrowend), Hstararrowtxt, fontsize, Kstararrowtxt, fontsize, Lstararrowtxt, fontsize) # Make colour gradient array used for drawing a bar of colours next to associated values on the rendered html mincolourscalar = self.othermindata[self.icolourcol] maxcolourscalar = self.othermaxdata[self.icolourcol] if self.settings.sigma_color: mincolourscalar = self.otherminsigmas[self.icolourcol] maxcolourscalar = self.othermaxsigmas[self.icolourcol] span = maxcolourscalar - mincolourscalar ln = 60 incr = span / ln colourgradarrays = [] val = mincolourscalar colourscalararray = flex.double() colourscalararray.append(val) for j, sc in enumerate(range(ln)): val += incr colourscalararray.append(val) if self.otherscenes[self.icolourcol].miller_array.is_complex_array(): # When displaying phases from map coefficients together with fom values # compute colour map chart as a function of fom and phase values (x,y axis) incr = 360.0 / ln val = 0.0 colourscalararray = flex.double() colourscalararray.append(val) for j in enumerate(range(ln)): val += incr colourscalararray.append(val) fomarrays = [] if self.otherscenes[self.icolourcol].isUsingFOMs(): fomln = 50 fom = 1.0 fomdecr = 1.0 / (fomln - 1.0) # make fomln fom arrays of size len(colourscalararray) when calling colour_by_phi_FOM for j in range(fomln): fomarrays.append(flex.double(len(colourscalararray), fom)) fom -= fomdecr for j in range(fomln): colourgradarrays.append( graphics_utils.colour_by_phi_FOM( colourscalararray * (math.pi / 180.0), fomarrays[j]) * 255.0) else: fomln = 1 fomarrays = [1.0] colourgradarrays.append( graphics_utils.colour_by_phi_FOM(colourscalararray * (math.pi / 180.0)) * 255.0) else: fomln = 1 fomarrays = [1.0] colourgradarrays.append( graphics_utils.color_by_property( properties=flex.double(colourscalararray), selection=flex.bool(len(colourscalararray), True), color_all=False, gradient_type=self.settings.color_scheme) * 255.0) colors = self.otherscenes[self.icolourcol].colors radii = self.otherscenes[self.iradiicol].radii points = self.scene.points hkls = self.scene.indices dres = self.scene.dres colstr = self.scene.miller_array.info().label_string() data = self.scene.data colourlabel = self.otherscenes[self.icolourcol].colourlabel fomlabel = self.otherscenes[self.icolourcol].fomlabel #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) assert (colors.size() == radii.size() == nrefls) colours = [] positions = [] radii2 = [] spbufttips = [] self.workingbinvals = [] if not self.binarray == "Resolution": ibinarray = int(self.binarray) self.workingbinvals = [ self.othermindata[ibinarray] - 0.1, self.othermaxdata[ibinarray] + 0.1 ] self.workingbinvals.extend(self.binvals) self.workingbinvals.sort() if self.workingbinvals[0] < 0.0: self.workingbinvals.append(0.0) self.workingbinvals.sort() bindata = self.otherscenes[ibinarray].data if self.otherscenes[ibinarray].work_array.is_complex_array(): bindata = self.otherscenes[ibinarray].ampl else: self.workingbinvals = self.binvals colstr = "dres" bindata = 1.0 / dres self.nbin = len(self.workingbinvals) for ibin in range(self.nbin): colours.append([]) # colours and positions are 3 x size of data() positions.append([]) radii2.append([]) spbufttips.append([]) def data2bin(d): for ibin, binval in enumerate(self.workingbinvals): if (ibin + 1) == self.nbin: return ibin if d > binval and d <= self.workingbinvals[ibin + 1]: return ibin #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) raise Sorry("Should never get here") #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) for i, hklstars in enumerate(points): # bin currently displayed data according to the values of another miller array ibin = data2bin(bindata[i]) spbufttip = 'H,K,L: %s, %s, %s' % (hkls[i][0], hkls[i][1], hkls[i][2]) spbufttip += '\ndres: %s ' % str(roundoff(dres[i])) spbufttip += '\' + AA + \'' for j, otherscene in enumerate(self.otherscenes): ocolstr = self.proc_arrays[j].info().label_string() odata = otherscene.data od = "" if self.proc_arrays[j].is_complex_array(): if not math.isnan(otherscene.foms[i]): od = str(roundoff(otherscene.ampl[i])) + ", " + str(roundoff(otherscene.phases[i]) ) + \ "\' + DGR + \'" + ", " + str(roundoff(otherscene.foms[i]) ) else: od = str(roundoff(otherscene.ampl[i])) + ", " + str(roundoff(otherscene.phases[i]) ) + \ "\' + DGR + \'" elif self.proc_arrays[j].sigmas() is not None: od = str(roundoff(odata[i])) + ", " + str( roundoff(otherscene.sigmas[i])) else: od = str(roundoff(odata[i])) if not (math.isnan(abs(odata[i])) or odata[i] == display.inanval): spbufttip += "\n%s: %s" % (ocolstr, od) positions[ibin].extend(roundoff(list(hklstars))) colours[ibin].extend(roundoff(list(colors[i]), 2)) radii2[ibin].append(roundoff(radii[i], 2)) spbufttips[ibin].append(spbufttip) spherebufferstr = """ ttips = new Array(%d) positions = new Array(%d) colours = new Array(%d) radii = new Array(%d) spherebufs = new Array(%d) """ % (self.nbin, self.nbin, self.nbin, self.nbin, self.nbin) negativeradiistr = "" cntbin = 0 self.binstrs = [] for ibin in range(self.nbin): mstr = "" nreflsinbin = len(radii2[ibin]) if (ibin + 1) < self.nbin and nreflsinbin > 0: bin1 = self.workingbinvals[ibin] bin2 = self.workingbinvals[ibin + 1] if colstr == "dres": bin1 = 1.0 / self.workingbinvals[ibin] bin2 = 1.0 / self.workingbinvals[ibin + 1] mstr= "bin:%d, %d reflections with %s in ]%2.2f; %2.2f]" %(cntbin, nreflsinbin, \ colstr, bin1, bin2) self.binstrs.append(mstr) self.mprint(mstr, verbose=True) spherebufferstr += """ // %s ttips[%d] = %s positions[%d] = new Float32Array( %s ) colours[%d] = new Float32Array( %s ) radii[%d] = new Float32Array( %s ) spherebufs[%d] = new NGL.SphereBuffer({ position: positions[%d], color: colours[%d], radius: radii[%d], picking: ttips[%d], }) //}, { disableImpostor: true }) // if true allows wireframe spheres but does not allow resizing spheres shape.addBuffer(spherebufs[%d]) """ %(mstr, cntbin, str(spbufttips[ibin]).replace('\"', '\''), \ cntbin, str(positions[ibin]), cntbin, str(colours[ibin]), \ cntbin, str(radii2[ibin]), cntbin, cntbin, cntbin, cntbin, cntbin, cntbin ) if self.workingbinvals[ibin] < 0.0: negativeradiistr += "spherebufs[%d].setParameters({metalness: 1})\n" % cntbin cntbin += 1 spherebufferstr += """ // create tooltip element and add to the viewer canvas tooltip = document.createElement("div"); Object.assign(tooltip.style, { display: "none", position: "absolute", zIndex: 10, pointerEvents: "none", backgroundColor: "rgba(255, 255, 255, 0.75)", color: "black", padding: "0.1em", fontFamily: "sans-serif" }); stage.viewer.container.appendChild(tooltip); // listen to `hovered` signal to move tooltip around and change its text stage.signals.hovered.add(function (pickingProxy) { if (pickingProxy && (Object.prototype.toString.call(pickingProxy.picker) === '[object Array]' )){ var sphere = pickingProxy.sphere; var cp = pickingProxy.canvasPosition; tooltip.innerText = pickingProxy.picker[pickingProxy.pid]; tooltip.style.bottom = cp.y + 7 + "px"; tooltip.style.left = cp.x + 8 + "px"; tooltip.style.fontSize = "smaller"; tooltip.style.display = "block"; }else{ tooltip.style.display = "none"; } }); stage.signals.clicked.add(function (pickingProxy) { if (pickingProxy && (Object.prototype.toString.call(pickingProxy.picker) === '[object Array]' )){ var innerText = pickingProxy.picker[pickingProxy.pid]; mysocket.send( innerText); } }); """ colourgradstrs = "colourgradvalarray = new Array(%s)\n" % fomln # if displaying phases from map coefficients together with fom values then for g, colourgradarray in enumerate(colourgradarrays): self.colourgradientvalues = [] for j, e in enumerate(colourgradarray): self.colourgradientvalues.append([colourscalararray[j], e]) self.colourgradientvalues = roundoff(self.colourgradientvalues) fom = fomarrays[g] colourgradstr = [] for j, val in enumerate(self.colourgradientvalues): vstr = "" alpha = 1.0 gradval = "rgba(%s, %s, %s, %s)" % (val[1][0], val[1][1], val[1][2], alpha) if j % 10 == 0 or j == len(self.colourgradientvalues) - 1: vstr = str(roundoff(val[0], 2)) colourgradstr.append([vstr, gradval]) colourgradstrs += " colourgradvalarray[%s] = %s\n" % ( g, str(colourgradstr)) #negativeradiistr = "" #for ibin in range(self.nbin): # if self.workingbinvals[ibin] < 0.0: # negativeradiistr += "spherebufs[%d].setParameters({metalness: 1})\n" %ibin self.NGLscriptstr = """ // Microsoft Edge users follow instructions on // https://stackoverflow.com/questions/31772564/websocket-to-localhost-not-working-on-microsoft-edge // to enable websocket connection var pagename = location.pathname.substring(1); var mysocket = new WebSocket('ws://127.0.0.1:7894/'); mysocket.onopen = function (e) { mysocket.send('%s now connected via websocket to ' + pagename + '\\n'); }; mysocket.onclose = function (e) { mysocket.send('%s now disconnecting from websocket ' + pagename + '\\n'); }; // Log errors to debugger of your browser mysocket.onerror = function (error) { console.log('WebSocket Error ' + error); }; window.addEventListener( 'resize', function( event ){ stage.handleResize(); }, false ); var stage; var shape; var shapeComp; var repr; var AA = String.fromCharCode(197); // short for angstrom var DGR = String.fromCharCode(176); // short for degree symbol function createElement (name, properties, style) { // utility function used in for loop over colourgradvalarray var el = document.createElement(name) Object.assign(el, properties) Object.assign(el.style, style) Object.assign(el.style, { display: "block", position: "absolute", color: "black", fontFamily: "sans-serif", fontSize: "smaller", } ) return el } function addElement (el) { // utility function used in for loop over colourgradvalarray Object.assign(el.style, { position: "absolute", zIndex: 10 }) stage.viewer.container.appendChild(el) } function addDivBox(txt, t, l, w, h, bgcolour='rgba(255.0, 255.0, 255.0, 0.0)') { divbox = createElement("div", { innerText: txt }, { backgroundColor: bgcolour, color: 'rgba(0.0, 0.0, 0.0, 1.0)', top: t.toString() + "px", left: l.toString() + "px", width: w.toString() + "px", height: h.toString() + "px", } ); addElement(divbox) } var hklscene = function () { shape = new NGL.Shape('shape'); stage = new NGL.Stage('viewport', { backgroundColor: "grey", tooltip:false, fogNear: 100, fogFar: 100 }); stage.setParameters( { cameraType: "%s" } ); %s %s shapeComp = stage.addComponentFromObject(shape); repr = shapeComp.addRepresentation('buffer'); shapeComp.autoView(); repr.update() // if some radii are negative draw them with wireframe %s //colourgradvalarrays %s var ih = 3; var topr = 35 var topr2 = 10 var lp = 10 var wp = 40 var lp2 = lp + wp var gl = 3 var wp2 = gl var fomlabelheight = 25 if (colourgradvalarray.length === 1) { wp2 = 15 fomlabelheight = 0 } var wp3 = wp + colourgradvalarray.length * wp2 + 2 totalheight = ih*colourgradvalarray[0].length + 35 + fomlabelheight // make a white box on top of which boxes with transparent background are placed // containing the colour values at regular intervals as well as label legend of // the displayed miller array addDivBox("", topr2, lp, wp3, totalheight, 'rgba(255.0, 255.0, 255.0, 1.0)'); // print label of the miller array used for colouring addDivBox("%s", topr2, lp, wp, 20); if (colourgradvalarray.length > 1) { // print FOM label, 1, 0.5 and 0.0 values below colour chart fomtop = topr2 + totalheight - 18 fomlp = lp + wp fomwp = wp3 fomtop2 = fomtop - 13 // print the 1 number addDivBox("1", fomtop2, fomlp, fomwp, 20) // print the 0.5 number leftp = fomlp + 0.48 * gl * colourgradvalarray.length addDivBox("0.5", fomtop2, leftp, fomwp, 20) // print the FOM label addDivBox("%s", fomtop, leftp, fomwp, 20); // print the 0 number leftp = fomlp + 0.96 * gl * colourgradvalarray.length addDivBox("0", fomtop2, leftp, fomwp, 20) } for (j = 0; j < colourgradvalarray[0].length; j++) { rgbcol = colourgradvalarray[0][j][1]; val = colourgradvalarray[0][j][0] topv = j*ih + topr toptxt = topv - 5 // print value of miller array if present in colourgradvalarray[0][j][0] addDivBox(val, toptxt, lp, wp, ih); } // draw the colour gradient for (g = 0; g < colourgradvalarray.length; g++) { leftp = g*gl + lp + wp // if FOM values are supplied draw colour gradients with decreasing // saturation values as stored in the colourgradvalarray[g] arrays for (j = 0; j < colourgradvalarray[g].length; j++) { rgbcol = colourgradvalarray[g][j][1]; val = colourgradvalarray[g][j][0] topv = j*ih + topr addDivBox("", topv, leftp, wp2, ih, rgbcol); } } } document.addEventListener('DOMContentLoaded', function() { hklscene() }, false ); mysocket.onmessage = function (e) { //alert('Server: ' + e.data); var c var alpha var si mysocket.send('got ' + e.data ); // tell server what it sent us try { val = e.data.split(",") if (val[0] === "alpha") { ibin = parseInt(val[1]) alpha = parseFloat(val[2]) spherebufs[ibin].setParameters({opacity: alpha}) stage.viewer.requestRender() } if (val[0] === "colour") { ibin = parseInt(val[1]) si = parseInt(val[2]) colours[ibin][3*si] = parseFloat(val[3]) colours[ibin][3*si+1] = parseFloat(val[4]) colours[ibin][3*si+2] = parseFloat(val[5]) spherebufs[ibin].setAttributes({ color: colours[ibin] }) stage.viewer.requestRender() } if (val[0] === "Redraw") { stage.viewer.requestRender() } if (val[0] === "ReOrient") { mysocket.send( 'Reorienting ' + pagename ); sm = new Float32Array(16); for (j=0; j<16; j++) sm[j] = parseFloat(val[j + 2]) // first 2 are "ReOrient", "NGL\\n" var m = new NGL.Matrix4(); m.fromArray(sm); stage.viewerControls.orient(m); stage.viewer.requestRender(); } if (val[0] === "Reload") { // refresh browser with the javascript file cvorient = stage.viewerControls.getOrientation().elements msg = String(cvorient) mysocket.send('Current vieworientation:\\n, ' + msg ); mysocket.send( 'Refreshing ' + pagename ); window.location.reload(true); } if (val[0] === "Testing") { // test something new mysocket.send( 'Testing something new ' + pagename ); var newradii = radii[0].map(function(element) { return element*1.5; }); spherebufs[0].setAttributes({ radius: newradii }) stage.viewer.requestRender() } } catch(err) { mysocket.send('error: ' + err ); } }; """ % (self.__module__, self.__module__, self.cameratype, arrowstr, spherebufferstr, \ negativeradiistr, colourgradstrs, colourlabel, fomlabel) if self.jscriptfname: with open(self.jscriptfname, "w") as f: f.write(self.NGLscriptstr) self.ReloadNGL()