Exemple #1
0
def correct_intensities_for_dac_attenuation(
    experiment: Experiment,
    reflections: flex.reflection_table,
    dac_norm: Vector,
    thickness: float,
    density: float = 3.51,
) -> None:
    """
    Boost integrated intensities to account for attenuation by a diamond anvil cell.

    Take an experiment object and reflection table containing integrated but unscaled
    diffraction data, boost the integrated reflection intensities to correct for the
    estimated attenuation due to the passage of the incident and diffracted beams
    through the diamond anvils.

    Args:
        experiment:  An experiment from integrated data.
        reflections:  A table of reflections from integrated data.
        dac_norm:  A 3-vector representing the normal to the anvil surfaces in the
                   laboratory frame when the goniometer is at zero datum, i.e. the axes
                   are all at 0°.  The vector is assumed to be normalised.
        thickness:  The thickness of each diamond anvil (assumed equal).
        density:  The density of the anvil material in g·cm⁻³
                  (units chosen for consistency with the NIST tables of X-ray mass
                  attenuation coefficients, https://dx.doi.org/10.18434/T4D01F).
                  Defaults to a typical value for synthetic diamond.
    """
    # Select only those reflections whose intensities after integration ought to be
    # meaningful.
    sel = reflections.get_flags(reflections.flags.integrated, all=False)
    sel = sel.iselection()
    refls_sel = reflections.select(sel)

    correction = attenuation_correction(experiment, refls_sel, dac_norm,
                                        thickness, density)

    # We need only correct non-null values for each integration method.
    prf_subsel = refls_sel.get_flags(refls_sel.flags.integrated_prf)
    sum_subsel = refls_sel.get_flags(refls_sel.flags.integrated_sum)

    # Correct the measured intensities and variances for this attenuation.
    methods = {"prf": prf_subsel, "sum": sum_subsel}
    quantities = {"value": correction, "variance": flex.pow2(correction)}
    for method, subsel in methods.items():
        setting_subsel = sel.select(subsel)
        for quantity, factor in quantities.items():
            col = f"intensity.{method}.{quantity}"
            corrected = (refls_sel[col] * factor).select(subsel)
            try:
                reflections[col].set_selected(setting_subsel, corrected)
            except KeyError:
                pass
Exemple #2
0
def preprocess(
    experiments: ExperimentList,
    observed: flex.reflection_table,
    params: phil.scope_extract,
) -> Tuple[List[flex.reflection_table], phil.scope_extract, List[str]]:
    reflections = observed.split_by_experiment_id()

    if len(reflections) != len(experiments):
        # spots may not have been found on every image. In this case, the length
        # of the list of reflection tables will be less than the length of experiments.
        # Add in empty items to the list, so that this can be reported on
        no_refls = set(range(len(experiments))).difference(set(observed["id"]))
        for i in no_refls:
            reflections.insert(i, None)
        if len(experiments) != len(reflections):
            raise ValueError(
                f"Unequal number of reflection tables {len(reflections)} and experiments {len(experiments)}"
            )

    # Calculate necessary quantities
    for refl, experiment in zip(reflections, experiments):
        if refl:
            elist = ExperimentList([experiment])
            refl["imageset_id"] = flex.int(refl.size(),
                                           0)  # needed for centroid_px_to_mm
            refl.centroid_px_to_mm(elist)
            refl.map_centroids_to_reciprocal_space(elist)

    # Determine the max cell if applicable
    if (params.indexing.max_cell is
            Auto) and (not params.indexing.known_symmetry.unit_cell):
        if params.individual_log_verbosity <= 2:  # suppress the max cell debug log
            logging.getLogger("dials.algorithms.indexing.max_cell").setLevel(
                logging.INFO)
        max_cells = []
        for refl in reflections:
            if refl:
                try:
                    max_cells.append(find_max_cell(refl).max_cell)
                except (DialsIndexError, AssertionError):
                    pass
        if not max_cells:
            raise ValueError("Unable to find a max cell for any images")
        logger.info(f"Setting max cell to {max(max_cells):.1f} " + "\u212B")
        params.indexing.max_cell = max(max_cells)

    # Determine which methods to try
    method_list = params.method
    if "real_space_grid_search" in method_list:
        if not params.indexing.known_symmetry.unit_cell:
            logger.info(
                "No unit cell given, real_space_grid_search will not be used")
            method_list.remove("real_space_grid_search")
    methods = ", ".join(method_list)
    pl = "s" if (len(method_list) > 1) else ""
    logger.info(f"Attempting indexing with {methods} method{pl}")

    return reflections, params, method_list
Exemple #3
0
def sum_integrate_and_update_table(
        reflections: reflection_table,
        image_volume: MultiPanelImageVolume = None) -> reflection_table:
    """Perform 3D summation integration and update a reflection table.

    Arguments:
        reflections: The reflections to integrate

    Returns:
        The integrated reflections
    """

    # Integrate and return the reflections
    if image_volume is None:
        intensity = reflections["shoebox"].summed_intensity()
    else:
        intensity = sum_image_volume(reflections, image_volume)
    reflections["intensity.sum.value"] = intensity.observed_value()
    reflections["intensity.sum.variance"] = intensity.observed_variance()
    reflections["background.sum.value"] = intensity.background_value()
    reflections["background.sum.variance"] = intensity.background_variance()
    success = intensity.observed_success()
    reflections.set_flags(success, reflections.flags.integrated_sum)
    return success
Exemple #4
0
def filter_reflection_table(reflection_table: flex.reflection_table,
                            intensity_choice: List[str], *args: Any,
                            **kwargs: Any) -> flex.reflection_table:
    """Filter the data and delete unneeded intensity columns.

    A list of which intensities to filter on e.g "sum", "scale", "profile" or
    allowed combinations. If a combination is given, only those reflections
    which have valid reflections for the multiple intensity types are retained.

    Strict checks are made that the requested intensity choice(s) has the
    required data in the reflection table.

    Args:
        reflection_table: a single reflection table object
        intensity_choice[List]: a list of the which intensities to filter on

    Returns:
        A reflection table filtered based on the arguments (of reduced size
        compared to the input table.)

    Raises:
        ValueError: if invalid intensity_choice given, if one step of filtering
            causes no reflections to remain, if no profile reflections remain
            after filtering and the choice is "profile".
    """
    if not isinstance(intensity_choice, list):
        raise ValueError("intensity_choice must be List[str]")

    if intensity_choice == ["scale"]:
        reducer: Type[FilterForExportAlgorithm] = ScaleIntensityReducer
    elif intensity_choice == ["sum"]:
        reducer = SumIntensityReducer
    elif intensity_choice == ["profile"]:
        reducer = PrfIntensityReducer
    elif all(i in intensity_choice for i in ["sum", "scale", "profile"]):
        reducer = AllSumPrfScaleIntensityReducer
    elif all(i in intensity_choice for i in ["sum", "profile"]):
        reducer = SumAndPrfIntensityReducer
    elif all(i in intensity_choice for i in ["sum | profile"]):
        reducer = SumORPrfIntensityReducer
    elif all(i in intensity_choice for i in ["sum", "scale"]):
        reducer = SumAndScaleIntensityReducer
    else:
        raise ValueError((
            "Unrecognised intensity choice for filter_reflection_table,\n"
            "value read: {}\n"
            "must be one of: 'scale', 'profile', 'sum', 'profile sum', \n"
            "                'sum scale', 'profile sum scale'\n"
            "(if parsing from command line, multiple choices passed as e.g. profile+sum"
        ).format(intensity_choice))
    # Validate that the reflection table has the columns we need
    required_columns_lookup = {
        "scale": {"inverse_scale_factor", "intensity.scale.value"},
        "profile": {"intensity.prf.value"},
        "sum": {"intensity.sum.value"},
    }
    for intensity_kind, required_columns in required_columns_lookup.items():
        if intensity_kind in intensity_choice:
            missing_columns = required_columns - set(reflection_table.keys())
            if missing_columns:
                raise ValueError(
                    "Cannot export intensity kind '{}'; missing column(s): {}".
                    format(intensity_kind, ", ".join(missing_columns)))

    # Do the filtering, but with an exception for the case of no profile fitted
    # reflections - in this case, try to reprocess without profile fitted.
    try:
        reflection_table = reducer.filter_for_export(reflection_table, *args,
                                                     **kwargs)
    except NoProfilesException as e:
        logger.warning(e, exc_info=True)
        if "profile" in intensity_choice:
            intensity_choice.remove("profile")
        else:
            intensity_choice = None
        if intensity_choice:
            logger.info(
                "Attempting to reprocess with intensity choice: %s",
                " + ".join(i for i in intensity_choice),
            )
            reflection_table = filter_reflection_table(reflection_table,
                                                       intensity_choice, *args,
                                                       **kwargs)
        else:
            raise ValueError(
                "Unable to process data due to absence of profile fitted reflections"
            )
    return reflection_table