Exemple #1
0
def nth_power_scale(dataarray, nth_power):
  """
  set nth_power to appropriate number between 0 and 1 for dampening the
  difference between the smallest and the largest values.
  If nth_power < 0 then an automatic value is computed that maps the smallest
  values to 0.1 of the largest values
  """
  absdat = flex.abs(dataarray).as_double()
  absdat2 = graphics_utils.NoNansArray(absdat) # much faster than flex.double([e for e in absdat if not math.isnan(e)])
  maxdat = flex.max(absdat2)
  mindat = max(1e-10*maxdat, flex.min(absdat2) )
  # only autoscale for sensible values of maxdat and mindat
  if nth_power < 0.0 and maxdat > mindat : # amounts to automatic scale
    nth_power = math.log(0.2)/(math.log(mindat) - math.log(maxdat))
  datascaled = flex.pow(absdat, nth_power)
  return datascaled, nth_power
Exemple #2
0
def nth_power_scale(dataarray, nth_power):
    """
  set nth_power to a number for dampening or enhancing the
  difference between the smallest and the largest values.
  A negative number means that a large data value is rendered with a smaller radius than
  a small data value. For nth_power=0 all data values are rendered with the same radius
  For nth_power=1 data values are rendered with radii proportional to the data values.
  If nth_power=NaN then an automatic value is computed that maps the smallest
  values to 0.1 of the largest values
  """
    absdat = flex.abs(dataarray).as_double()
    absdat2 = graphics_utils.NoNansArray(
        absdat
    )  # much faster than flex.double([e for e in absdat if not math.isnan(e)])
    maxdat = flex.max(absdat2)
    mindat = max(1e-10 * maxdat, flex.min(absdat2))
    # only autoscale for sensible values of maxdat and mindat
    if math.isnan(nth_power) and maxdat > mindat:  # amounts to automatic scale
        nth_power = math.log(0.2) / (math.log(mindat) - math.log(maxdat))
    datascaled = flex.pow(absdat, nth_power)
    return datascaled, nth_power
Exemple #3
0
 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 __init__(self, millarr, wrap_labels=0):
        from cctbx.miller import display2
        from cctbx.array_family import flex
        from scitbx import graphics_utils
        from libtbx.math_utils import roundoff
        import math
        nan = float("nan")
        self.wrap_labels = wrap_labels
        if millarr.space_group() is None:
            self.spginf = "?"
        else:
            self.spginf = millarr.space_group_info().symbol_and_number()
        if millarr.unit_cell() is None:
            self.ucell = (nan, nan, nan, nan, nan, nan)
        else:
            self.ucell = millarr.unit_cell().parameters()
        self.ucellinf = "({:.6g}Å, {:.6g}Å, {:.6g}Å, {:.6g}°, {:.6g}°, {:.6g}°)".format(
            *self.ucell)
        data = millarr.deep_copy().data()
        self.maxdata = self.mindata = self.maxsigmas = self.minsigmas = nan
        self.minmaxdata = (nan, nan)
        self.minmaxsigs = (nan, nan)
        self.data_sigdata_max = nan
        self.data_sigdata = nan
        self.desc = ""
        self.arrsize = data.size()
        if not isinstance(data, flex.std_string):
            if isinstance(data, flex.hendrickson_lattman):
                data = graphics_utils.NoNansHL(data)
                # estimate minmax values of HL coefficients as a simple sum
                if self.arrsize:
                    self.maxdata = max(
                        [e[0] + e[1] + e[2] + e[3] for e in data])
                    self.mindata = min(
                        [e[0] + e[1] + e[2] + e[3] for e in data])
                    self.arrsize = len([
                        42 for e in millarr.data()
                        if not math.isnan(e[0] + e[1] + e[2] + e[3])
                    ])
            elif isinstance(data, flex.vec3_double) or isinstance(
                    data, flex.vec2_double):
                # XDS produces 2D or 3D arrays in some of its files
                if self.arrsize:
                    self.maxdata = max([max(e) for e in data])
                    self.mindata = min([min(e) for e in data])
            else:
                # Get a list of bools with True whenever there is a nan
                selection = ~graphics_utils.IsNans(
                    flex.abs(millarr.data()).as_double())
                # count elements that are not nan values
                self.arrsize = millarr.data().select(selection).size()
                if (isinstance(data, flex.int)):
                    data = flex.double(
                        [e for e in data if e != display2.inanval])
                if millarr.is_complex_array():
                    data = flex.abs(data)
                i = 0
                while math.isnan(data[i]):
                    i += 1  # go on until we find a data[i] that isn't NaN
                data = graphics_utils.NoNansArray(
                    data, data[i])  # assuming data[0] isn't NaN
                self.maxdata = flex.max(data)
                self.mindata = flex.min(data)
            if millarr.sigmas() is not None:
                data = millarr.sigmas().deep_copy()
                i = 0
                while math.isnan(data[i]):
                    i += 1  # go on until we find a data[i] that isn't NaN
                data = graphics_utils.NoNansArray(data, data[i])
                self.maxsigmas = flex.max(data)
                self.minsigmas = flex.min(data)
                # Inspired by Diederichs doi:10.1107/S0907444910014836 I/SigI_asymptotic
                data_over_sigdata = millarr.data() / millarr.sigmas()
                self.data_sigdata = flex.sum(data_over_sigdata) / len(
                    data_over_sigdata)
                self.data_sigdata_max = flex.max(data_over_sigdata)
            self.minmaxdata = (self.mindata, self.maxdata)
            self.minmaxsigs = (self.minsigmas, self.maxsigmas)
        self.labels = self.desc = self.wavelength = ""
        if millarr.info():
            self.labels = millarr.info().labels
            self.desc = get_array_description(millarr)
            self.wavelength = "{:.6g}".format(
                millarr.info().wavelength) if millarr.info(
                ).wavelength is not None else float("nan")
        self.span = "(?,?,?), (?,?,?)"
        self.dmin = nan
        self.dmax = nan
        if millarr.unit_cell() is not None:
            self.span = str(millarr.index_span().min()) + ", " + str(
                millarr.index_span().max())
            self.dmin = millarr.d_max_min()[1]
            self.dmax = millarr.d_max_min()[0]
        self.dminmax = roundoff((self.dmin, self.dmax))
        self.issymunique = "?"
        self.isanomalous = "?"
        self.n_sys_abs = 0
        self.n_bijvoet = self.n_singletons = 0
        self.ano_mean_diff = nan
        self.ano_completeness = nan
        self.data_compl_infty = nan
        self.data_completeness = nan
        self.n_centric = nan
        # computations below done as in cctbx.miller.set.show_comprehensive_summary()
        if self.spginf != "?":
            self.issymunique = millarr.is_unique_set_under_symmetry()
            self.isanomalous = millarr.anomalous_flag()
            sys_absent_flags = millarr.sys_absent_flags().data()
            self.n_sys_abs = sys_absent_flags.count(True)
            if (self.n_sys_abs != 0):
                millarr = millarr.select(selection=~sys_absent_flags)
            self.n_centric = millarr.centric_flags().data().count(True)
        if not math.isnan(self.ucell[0]):
            if (self.spginf != "?" and millarr.indices().size() > 0
                    and self.issymunique):
                millarr.setup_binner(n_bins=1)
                completeness_d_max_d_min = millarr.completeness(
                    use_binning=True)
                binner = completeness_d_max_d_min.binner
                assert binner.counts_given()[0] == 0
                assert binner.counts_given()[2] == 0
                n_obs = binner.counts_given()[1]
                n_complete = binner.counts_complete()[1]
                if (n_complete != 0 and self.dmax != self.dmin):
                    self.data_completeness = n_obs / n_complete
                n_complete += binner.counts_complete()[0]
                if (n_complete != 0):
                    self.data_compl_infty = n_obs / n_complete
                if (self.isanomalous) and (millarr.is_xray_intensity_array() or
                                           millarr.is_xray_amplitude_array()):
                    self.ano_completeness = millarr.anomalous_completeness()
        if (self.spginf != "?" and self.isanomalous and self.issymunique):
            asu, matches = millarr.match_bijvoet_mates()
            self.n_bijvoet = matches.pairs().size()
            self.n_singletons = matches.n_singles() - self.n_centric
            if millarr.is_real_array():
                self.ano_mean_diff = millarr.anomalous_signal()
        # break long label into list of shorter strings
        self.labelstr = ",".join(self.labels)
        if self.wrap_labels > 0:
            tlabels = textwrap.wrap(self.labelstr, width=self.wrap_labels)
            nlabl = len(tlabels)
            self.labelsformat = "{0[0]:>%d} " % (1 + self.wrap_labels)
            if len(tlabels) > 1:
                for i in range((len(tlabels) - 1)):
                    self.labelsformat += "\n{0[%d]:>%d} " % (
                        i + 1, self.wrap_labels + 1)
            blanks = self.wrap_labels - 5
        else:
            self.labelsformat = "{:>16} "
            if len(self.labelstr) > 15:
                self.labelsformat = "{}\n                 "
            blanks = 10

        self.info_format_dict = {
            # the keys here must be verbatim copies of names of phil attributes in arrayinfo_phil_str below
            "labels": (" %s" % self.caption_dict["labels"][0] + " " * blanks,
                       self.labelstr, "{}", self.labelsformat),
            "description":
            ("       %s      " % self.caption_dict["description"][0],
             self.desc, "{}", "{:>16} "),
            "wavelength": ("   %s   " % self.caption_dict["wavelength"][0],
                           self.wavelength, "{}", "{:>8} "),
            "n_reflections": ("  %s  " % self.caption_dict["n_reflections"][0],
                              self.arrsize, "{}", "{:>8} "),
            "span": (" " * 15 + self.caption_dict["span"][0] + " " * 14,
                     self.span, "{}", "{:>32} "),
            "minmax_data":
            ("     %s       " % self.caption_dict["minmax_data"][0],
             self.minmaxdata, "{0[0]:.6}, {0[1]:.6}",
             "{0[0]:>11.5}, {0[1]:>11.5}"),
            "minmax_sigmas":
            ("     %s     " % self.caption_dict["minmax_sigmas"][0],
             self.minmaxsigs, "{0[0]:.6}, {0[1]:.6}",
             "{0[0]:>11.5}, {0[1]:>11.5}"),
            "data_sigdata": (" %s" % self.caption_dict["data_sigdata"][0],
                             self.data_sigdata, "{:.4g}", "{:>9.4g} "),
            "data_sigdata_max":
            ("%s" % self.caption_dict["data_sigdata_max"][0],
             self.data_sigdata_max, "{:.4g}", "{:>11.4g} "),
            "d_minmax": ("  %s   " % self.caption_dict["d_minmax"][0],
                         self.dminmax, "{0[0]:.6}, {0[1]:.6}",
                         "{0[0]:>8.5}, {0[1]:>8.5}"),
            "unit_cell":
            ("     %s      " % self.caption_dict["unit_cell"][0], self.ucell,
             "{0[0]:>7.5g},{0[1]:>7.5g},{0[2]:>7.5g},{0[3]:>7.5g},{0[4]:>7.5g},{0[5]:>7.5g}",
             "{0[0]:>7.5g},{0[1]:>7.5g},{0[2]:>7.5g},{0[3]:>7.5g},{0[4]:>7.5g},{0[5]:>7.5g} "
             ),
            "space_group":
            ("   %s      " % self.caption_dict["space_group"][0], self.spginf,
             "{}", "{:>19} "),
            "n_centrics": ("%s" % self.caption_dict["n_centrics"][0],
                           self.n_centric, "{}", "{:>8} "),
            "n_sys_abs": ("%s" % self.caption_dict["n_sys_abs"][0],
                          self.n_sys_abs, "{}", "{:>9} "),
            "data_completeness":
            ("%s" % self.caption_dict["data_completeness"][0],
             self.data_completeness, "{:.5g}", "{:>10.5g} "),
            "data_compl_infty":
            ("%s" % self.caption_dict["data_compl_infty"][0],
             self.data_compl_infty, "{:.5g}", "{:>9.5g} "),
            "is_anomalous": ("%s" % self.caption_dict["is_anomalous"][0],
                             str(self.isanomalous), "{}", "{:>8} "),
            "is_symmetry_unique":
            ("%s" % self.caption_dict["is_symmetry_unique"][0],
             str(self.issymunique), "{}", "{:>8} "),
            "ano_completeness":
            ("%s" % self.caption_dict["ano_completeness"][0],
             self.ano_completeness, "{:.5g}", "{:>11.5g} "),
            "ano_mean_diff": ("%s" % self.caption_dict["ano_mean_diff"][0],
                              self.ano_mean_diff, "{:.5g}", "{:>8.5g} "),
            "n_bijvoet": ("%s" % self.caption_dict["n_bijvoet"][0],
                          self.n_bijvoet, "{}", "{:>8} "),
            "n_singletons": ("%s" % self.caption_dict["n_singletons"][0],
                             self.n_singletons, "{}", "{:>10} "),
        }
Exemple #5
0
    def generate_view_data(self):
        from scitbx.array_family import flex
        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 isinstance(data, flex.complex_double):
            data_for_colors = self.phases
            foms_for_colours = self.foms
            # assuming last part of the labels indicates the phase label as in ["FCALC","PHICALC"]
            self.colourlabel = "Phase of " + self.miller_array.info(
            ).label_string()
        elif (settings.sigma_color_radius) and sigmas is not None:
            data_for_colors = sigmas.as_double()
            self.colourlabel = "Sigma of " + self.miller_array.info(
            ).label_string()
        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 (settings.sigma_color_radius) and sigmas is not None:
            data_for_radii, self.nth_power_scale_radii = nth_power_scale(
                flex.abs(sigmas.as_double().deep_copy()),
                settings.nth_power_scale_radii)
        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)
        # Computing rgb colours of each reflection is slow so make a small array
        # of precomputed colours to use as a lookup table for each reflection
        if isinstance(data, flex.complex_double):
            COL = MplColorHelper(settings.color_scheme, 0, 360)
            rgbcolarray = [COL.get_rgb(d)[0:3] for d in range(360)]
            if self.isUsingFOMs():
                colors = graphics_utils.map_to_rgb_colourmap(
                    data_for_colors=data_for_colors,
                    colormap=rgbcolarray,
                    selection=flex.bool(data_for_colors.size(), True),
                    attenuation=foms_for_colours,
                    map_directly=True,
                    color_all=False)
            else:
                colors = graphics_utils.map_to_rgb_colourmap(
                    data_for_colors=data_for_colors,
                    colormap=rgbcolarray,
                    selection=flex.bool(data_for_colors.size(), True),
                    attenuation=None,
                    map_directly=True,
                    color_all=False)
        else:
            # Use a colour gradient from matplotlib
            COL = MplColorHelper(settings.color_scheme, 0, 199)
            colorgradientarray = flex.vec3_double(
                [COL.get_rgb(d)[0:3] for d in range(200)])
            # Do the table lookup in C++ for speed improvement
            colors = graphics_utils.map_to_rgb_colourmap(
                data_for_colors=data_for_colors,
                colormap=colorgradientarray,
                selection=flex.bool(data_for_colors.size(), True),
                powscale=settings.color_powscale,
                attenuation=None,
                color_all=False)

        if (settings.slice_mode):
            colors = colors.select(self.slice_selection)
            data_for_radii = data_for_radii.select(self.slice_selection)
        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