dials.scale

Introduction

This program performs scaling on integrated datasets, which attempts to improve the internal consistency of the reflection intensities by correcting for various experimental effects. By default, a physically motivated scaling model is used, with a scale, decay (B-factor) and absorption correction. If the input files contain multiple datasets, all data will be scaled against a common target of unique reflection intensities.

The program outputs one scaled.refl file, which contains updated reflection intensities, variances and per-refelction scale factors, and one scaled.expt containing the scaling models. These values can then be used to merge the data with dials.merge for downstream structural solution. Alternatively, the scaled.expt and scaled.refl files can be passed back to dials.scale, and further scaling will be performed, starting from where the previous job finished.

A dials.scale.html file is also generated, containing interactive plots of merging statistics and scaling model plots.

Example use cases

Regular single-sequence scaling, with no absorption correction:

dials.scale integrated.refl integrated.expt physical.absorption_correction=False

Scaling multiple datasets, specifying a resolution limit:

dials.scale 1_integrated.refl 1_integrated.expt 2_integrated.refl 2_integrated.expt d_min=1.4

Incremental scaling (with different options per dataset):

dials.scale integrated.refl integrated.expt physical.scale_interval=10.0

dials.scale integrated_2.refl integrated_2.expt scaled.refl scaled.expt physical.scale_interval=15.0

Basic parameters

model = KB array dose_decay physical
output {
  log = dials.scale.log
  experiments = "scaled.expt"
  reflections = "scaled.refl"
  html = "dials.scale.html"
  json = None
  unmerged_mtz = None
  merged_mtz = None
  project_name = DIALS
}
anomalous = False
overwrite_existing_models = False
reflection_selection {
  method = *quasi_random intensity_ranges use_all random
  random {
    multi_dataset {
      Isigma_cutoff = 1.0
    }
  }
  best_unit_cell = None
}
weighting {
  error_model {
    basic {
    }
  }
}
cut_data {
}
scaling_options {
  check_consistent_indexing = False
}
cross_validation {
}
filtering {
  method = None deltacchalf
  deltacchalf {
    max_cycles = 6
    max_percent_removed = 10
    min_completeness = None
    mode = *dataset image_group
    group_size = 10
    stdcutoff = 4.0
  }
  output {
    scale_and_filter_results = "scale_and_filter_results.json"
  }
}
dataset_selection {
}

Full parameter definitions

model = KB array dose_decay physical
  .help = "Set scaling model to be applied to input datasets"
  .type = choice
  .expert_level = 0
KB
  .expert_level = 1
{
  decay_correction = True
    .help = "Option to turn off decay correction (for physical/array/KB
      "
            "     default models)."
    .type = bool
    .expert_level = 1
}
array
  .expert_level = 1
{
  decay_correction = True
    .help = "Option to turn off decay correction (a 2D grid of parameters as a"
            "function of rotation and resolution (d-value))."
    .type = bool
    .expert_level = 1
  decay_interval = 20.0
    .help = "Rotation (phi) interval between model parameters for the decay"
            "and absorption corrections."
    .type = float(value_min=1, allow_none=True)
    .expert_level = 1
  n_resolution_bins = 10
    .help = "Number of resolution bins to use for the decay term."
    .type = int(value_min=1, allow_none=True)
    .expert_level = 1
  absorption_correction = True
    .help = "Option to turn off absorption correction (a 3D grid of parameters"
            "as a function of rotation angle, detector-x and detector-y"
            "position)."
    .type = bool
    .expert_level = 1
  n_absorption_bins = 3
    .help = "Number of bins in each dimension (applied to both x and y) for"
            "binning the detector position for the absorption term of the"
            "array model."
    .type = int(value_min=1, allow_none=True)
    .expert_level = 1
  modulation_correction = False
    .help = "Option to turn on a detector correction for the array default"
            "model."
    .type = bool
    .expert_level = 2
  n_modulation_bins = 20
    .help = "Number of bins in each dimension (applied to both x and y) for"
            "binning the detector position for the modulation correction."
    .type = int(value_min=1, allow_none=True)
    .expert_level = 2
}
dose_decay
  .expert_level = 1
{
  scale_interval = 2.0
    .help = "Rotation (phi) interval between model parameters for the scale"
            "component."
    .type = float(value_min=1, allow_none=True)
    .expert_level = 1
  relative_B_correction = True
    .help = "Option to turn off relative B correction."
    .type = bool
    .expert_level = 1
  decay_correction = True
    .help = "Option to turn off decay correction."
    .type = bool
    .expert_level = 1
  share.decay = True
    .help = "Share the decay model between sweeps."
    .type = bool
    .expert_level = 1
  resolution_dependence = *quadratic linear
    .help = "Use a dose model that depends linearly or quadratically on 1/d"
    .type = choice
    .expert_level = 1
  absorption_correction = False
    .help = "Option to turn on spherical harmonic absorption correction."
    .type = bool
    .expert_level = 1
  lmax = 4
    .help = "Number of spherical harmonics to include for absorption"
            "correction, recommended to be no more than 6."
    .type = int(value_min=2, allow_none=True)
    .expert_level = 1
  surface_weight = 1e6
    .help = "Restraint weight applied to spherical harmonic terms in the"
            "absorption correction."
    .type = float(value_min=0, allow_none=True)
    .expert_level = 1
  fix_initial = True
    .help = "If performing full matrix minimisation, in the final cycle,"
            "constrain the initial parameter for more reliable parameter and"
            "scale factor error estimates."
    .type = bool
    .expert_level = 2
}
physical
  .expert_level = 1
{
  scale_interval = auto
    .help = "Rotation (phi) interval between model parameters for the scale"
            "component (auto scales interval depending on oscillation range)."
    .type = float(value_min=1, allow_none=True)
    .expert_level = 1
  decay_correction = True
    .help = "Option to turn off decay correction."
    .type = bool
    .expert_level = 1
  decay_interval = auto
    .help = "Rotation (phi) interval between model parameters for the decay"
            "component (auto scales interval depending on oscillation range)."
    .type = float(value_min=1, allow_none=True)
    .expert_level = 1
  decay_restraint = 1e-1
    .help = "Weight to weakly restrain B-values to 0."
    .type = float(value_min=0, allow_none=True)
    .expert_level = 2
  absorption_correction = auto
    .help = "Option to turn off absorption correction (default True if"
            "oscillation > 60.0)."
    .type = bool
    .expert_level = 1
  lmax = 4
    .help = "Number of spherical harmonics to include for absorption"
            "correction, recommended to be no more than 6."
    .type = int(value_min=2, allow_none=True)
    .expert_level = 1
  surface_weight = 1e6
    .help = "Restraint weight applied to spherical harmonic terms in the"
            "absorption correction."
    .type = float(value_min=0, allow_none=True)
    .expert_level = 1
  fix_initial = True
    .help = "If performing full matrix minimisation, in the final cycle,"
            "constrain the initial parameter for more reliable parameter and"
            "scale factor error estimates."
    .type = bool
    .expert_level = 2
}
output {
  log = dials.scale.log
    .help = "The log filename"
    .type = str
  experiments = "scaled.expt"
    .help = "Option to set filepath for output json."
    .type = str
  reflections = "scaled.refl"
    .help = "Option to set filepath for output pickle file of scaled
         "
            "     intensities."
    .type = str
  html = "dials.scale.html"
    .help = "Filename for html report."
    .type = str
  json = None
    .help = "Filename to save html report data in json format."
    .type = str
  unmerged_mtz = None
    .help = "Filename to export an unmerged_mtz file using dials.export."
    .type = str
  merged_mtz = None
    .help = "Filename to export a merged_mtz file."
    .type = str
  crystal_name = XTAL
    .help = "The crystal name to be exported in the mtz file metadata"
    .type = str
    .expert_level = 1
  project_name = DIALS
    .help = "The project name for the mtz file metadata"
    .type = str
  use_internal_variance = False
    .help = "Option to use internal spread of the intensities when merging
   "
            "          reflection groups and calculating sigI, rather than"
            "using the
              sigmas of the individual reflections."
    .type = bool
    .expert_level = 1
  merging.nbins = 20
    .help = "Number of bins to use for calculating and plotting merging stats."
    .type = int(allow_none=True)
    .expert_level = 1
  delete_integration_shoeboxes = True
    .help = "Discard integration shoebox data from scaling output, to help"
            "with memory management."
    .type = bool
    .expert_level = 2
}
anomalous = False
  .help = "Separate anomalous pairs in scaling and error model optimisation."
  .type = bool
  .expert_level = 0
overwrite_existing_models = False
  .help = "If True, create new scaling models for all datasets"
  .type = bool
  .expert_level = 0
reflection_selection {
  method = *quasi_random intensity_ranges use_all random
    .help = "Method to use when choosing a reflection subset for scaling model"
            "minimisation. The quasi_random option randomly selects"
            "reflections groups within a dataset, and also selects groups"
            "which have good connectedness across datasets for multi-dataset"
            "cases. The random option selects reflection groups randomly for"
            "both single and multi dataset scaling, so for a single dataset"
            "quasi_random == random. The intensity_ranges option uses the"
            "E2_range, Isigma_range and d_range options to the subset of"
            "reflections The use_all option uses all suitable reflections,"
            "which may be slow for large datasets."
    .type = choice
  random {
    multi_dataset {
      Isigma_cutoff = 1.0
        .help = "Minimum average I/sigma of reflection groups to use when"
                "selecting random reflections for minimisation."
        .type = float(allow_none=True)
    }
    min_groups = 2000
      .help = "The minimum number of symmetry groups to use during"
              "minimisation."
      .type = int(allow_none=True)
      .expert_level = 1
    min_reflections = 50000
      .help = "The minimum number of reflections to use during minimisation."
      .type = int(allow_none=True)
      .expert_level = 1
  }
  best_unit_cell = None
    .help = "Best unit cell value, to use when performing resolution cutting"
            "and merging statistics. If None, the median cell will be used."
    .type = unit_cell
  E2_range = 0.8, 5.0
    .help = "Minimum and maximum normalised E^2 value to used to select a"
            "subset of reflections for minimisation."
    .type = floats(size=2)
    .expert_level = 1
  Isigma_range = -5.0, 0.0
    .help = "Minimum and maximum I/sigma values used to select a subset of"
            "reflections for minimisation. A value of 0.0 for the maximum"
            "indicates that no upper limit should be applied."
    .type = floats(size=2)
    .expert_level = 1
  d_range = None
    .help = "Minimum and maximum d-values used to select a subset of"
            "reflections for minimisation."
    .type = floats(size=2)
    .expert_level = 1
  min_partiality = 0.95
    .help = "Minimum partiality to use when selecting reflections to use to"
            "determine the scaling model and error model."
    .type = float(allow_none=True)
    .expert_level = 2
  intensity_choice = profile sum *combine
    .help = "Option to choose from profile fitted or summation intensities,"
            "or
               an optimised combination of profile/sum."
    .type = choice
    .expert_level = 1
    .alias = intensity
  combine.Imid = None
    .help = "A list of values to try for the midpoint, for profile/sum"
            "combination
               calculation: the value with the lowest"
            "Rmeas will be chosen.
               0 and 1 are special values"
            "that can be supplied to include profile
               and sum"
            "respectively in the comparison."
    .type = floats
    .expert_level = 2
  combine.joint_analysis = True
    .help = "Option of whether to do intensity combination optimisation
      "
            "       separately (i.e. different Imid per dataset) or joint for
"
            "             multiple datasets"
    .type = bool
    .expert_level = 2
}
weighting {
  weighting_scheme = *invvar
    .help = "Weighting scheme used during Ih calculation. Weighting schemes
  "
            "           other than invvar and unity may trigger iterative"
            "reweighting
              during minimisation, which may be"
            "unstable for certain minimisation
              engines (LBFGS)."
    .type = choice
    .expert_level = 2
  error_model {
    error_model = *basic None
      .help = "The error model to use."
      .type = choice
      .expert_level = 1
    basic {
      a = None
        .help = "Used this fixed value for the error model 'a' parameter"
        .type = float(allow_none=True)
        .expert_level = 2
      b = None
        .help = "Used this fixed value for the error model 'b' parameter"
        .type = float(allow_none=True)
        .expert_level = 2
      min_Ih = 25.0
        .help = "Reflections with expected intensity above this value are to."
                "be used in error model minimisation."
        .type = float(allow_none=True)
        .expert_level = 2
      n_bins = 10
        .help = "The number of intensity bins to use for the error model"
                "optimisation."
        .type = int(allow_none=True)
        .expert_level = 2
    }
  }
}
cut_data {
  d_min = None
    .help = "Option to apply a high resolution cutoff for the dataset (i.e.
  "
            "            the chosen reflections have d > d_min)."
    .type = float(allow_none=True)
    .expert_level = 1
  d_max = None
    .help = "Option to apply a low resolution cutoff for the dataset (i.e.
   "
            "           the chosen reflections have d < d_max)."
    .type = float(allow_none=True)
    .expert_level = 1
  partiality_cutoff = 0.4
    .help = "Value below which reflections are removed from the dataset due
  "
            "            to low partiality."
    .type = float(allow_none=True)
    .expert_level = 1
  min_isigi = -5
    .help = "Value below which reflections are removed from the dataset due to"
            "low I/sigI in either profile or summation intensity estimates"
    .type = float(allow_none=True)
    .expert_level = 1
}
scaling_options {
  check_consistent_indexing = False
    .help = "If True, run dials.cosym on all data in the data preparation"
            "step, to ensure consistent indexing."
    .type = bool
  target_cycle = True
    .help = "Option to turn of initial round of targeted scaling
             "
            " if some datasets are already scaled."
    .type = bool
    .expert_level = 2
  only_target = False
    .help = "Option to only do targeted scaling if some datasets
             "
            " are already scaled."
    .type = bool
    .expert_level = 2
  only_save_targeted = True
    .help = "If only_target is true, this option to change whether the"
            "dataset
              that is being scaled will be saved on its"
            "own, or combined with the
              already scaled dataset."
    .type = bool
    .expert_level = 2
  target_model = None
    .help = "Path to cif file to use to calculate target intensities for
     "
            "        scaling."
    .type = path
    .expert_level = 2
  target_mtz = None
    .help = "Path to merged mtz file to use as a target for scaling."
    .type = path
    .expert_level = 2
  nproc = 1
    .help = "Number of blocks to divide the data into for minimisation.
      "
            "       This also sets the number of processes to use if the"
            "option is
              available."
    .type = int(value_min=1, allow_none=True)
    .expert_level = 2
  use_free_set = False
    .help = "Option to use a free set during scaling to check for"
            "overbiasing.
              This free set is used to calculate an"
            "RMSD, which is shown alongisde
              the 'working' RMSD"
            "during refinement, but is not currently used
              to"
            "terminate refinement or make any choices on the model."
    .type = bool
    .expert_level = 2
  free_set_percentage = 10.0
    .help = "Percentage of symmetry equivalent groups to use for the free"
            "set,
              if use_free_set is True."
    .type = float(allow_none=True)
    .expert_level = 2
  free_set_offset = 0
    .help = "Offset for choosing unique groups for the free set from the"
            "whole
               set of unique groups."
    .type = int(allow_none=True)
    .expert_level = 2
  full_matrix = True
    .help = "Option to turn off GN/LM refinement round used to determine
     "
            "         error estimates on scale factors."
    .type = bool
    .expert_level = 2
  outlier_rejection = *standard simple
    .help = "Choice of outlier rejection routine. Standard may take a
       "
            "significant amount of time to run for large datasets or high
    "
            "   multiplicities, whereas simple should be quick for these"
            "datasets."
    .type = choice
    .expert_level = 1
  outlier_zmax = 6.0
    .help = "Cutoff z-score value for identifying outliers based on their
    "
            "          normalised deviation within the group of equivalent"
            "reflections"
    .type = float(value_min=3, allow_none=True)
    .expert_level = 1
}
cross_validation {
  cross_validation_mode = multi single
    .help = "Choose the cross validation running mode, for a full description"
            "see the module docstring. Choice is used for testing a parameter"
            "that can only have discreet values (a choice or bool phil"
            "parameter). Variable is used for testing a parameter that can"
            "have a float or int value (that is also not a 'choice' type)."
            "Single just performs cross validation on one parameter"
            "configuration."
    .type = choice
    .expert_level = 2
  parameter = None
    .help = "Optimise a command-line parameter. The full phil path must be :"
            "specified e.g. physical.absorption_correction. The option"
            "parameter_values must also be specified, unless the parameter is"
            "a True/False option."
    .type = str
    .expert_level = 2
  parameter_values = None
    .help = "Parameter values to compare, entered as a string of space"
            "separated values."
    .type = strings
    .expert_level = 2
  nfolds = 1
    .help = "Number of cross-validation folds to perform. If nfolds > 1, the"
            "minimisation for each option is repeated nfolds times, with an"
            "incremental offset for the free set. The max number of folds"
            "allowed is 1/free_set_percentage; if set greater than this then"
            "the repetition will finish afer 1/free_set_percentage folds."
    .type = int(value_min=1, allow_none=True)
    .expert_level = 2
}
scaling_refinery
  .help = "Parameters to configure the refinery"
  .expert_level = 1
{
  engine = *SimpleLBFGS GaussNewton LevMar
    .help = "The minimisation engine to use for the main scaling algorithm"
    .type = choice
  refinement_order = *concurrent consecutive
    .help = "Choice of whether to refine all model components concurrently, or"
            "in a consecutive order as allowed/defined by the scaling model."
    .type = choice
    .expert_level = 2
  max_iterations = None
    .help = "Maximum number of iterations in refinement before termination."
            "None implies the engine supplies its own default."
    .type = int(value_min=1, allow_none=True)
  rmsd_tolerance = 0.0001
    .help = "Tolerance at which to stop scaling refinement. This is a"
            "relative
            value, the convergence criterion is (rmsd[i]"
            "- rmsd[i-1])/rmsd[i] <
            rmsd_tolerance."
    .type = float(value_min=1e-06, allow_none=True)
  full_matrix_engine = GaussNewton *LevMar
    .help = "The minimisation engine to use for a full matrix round of
       "
            "     minimisation after the main scaling, in order to determine
 "
            "           error estimates."
    .type = choice
  full_matrix_max_iterations = None
    .help = "Maximum number of iterations before termination in the full"
            "matrix
             minimisation round. None implies the engine"
            "supplies its own default."
    .type = int(value_min=1, allow_none=True)
}
filtering {
  method = None deltacchalf
    .help = "Choice of whether to do any filtering cycles, default None."
    .type = choice
  deltacchalf {
    max_cycles = 6
      .type = int(value_min=1, allow_none=True)
    max_percent_removed = 10
      .type = float(allow_none=True)
    min_completeness = None
      .help = "Desired minimum completeness, as a percentage (0 - 100)."
      .type = float(value_min=0, value_max=100, allow_none=True)
    mode = *dataset image_group
      .help = "Perform analysis on whole datasets or batch groups"
      .type = choice
    group_size = 10
      .help = "The number of images to group together when calculating delta"
              "cchalf in image_group mode"
      .type = int(value_min=1, allow_none=True)
    stdcutoff = 4.0
      .help = "Datasets with a ΔCC½ below (mean - stdcutoff*std) are removed"
      .type = float(allow_none=True)
  }
  output {
    scale_and_filter_results = "scale_and_filter_results.json"
      .help = "Filename for output json of scale and filter results."
      .type = str
  }
}
exclude_images = None
  .help = "Input in the format exp:start:end Exclude a range of images (start,"
          "stop) from the dataset with experiment identifier exp  (inclusive"
          "of frames start, stop)."
  .type = strings
  .multiple = True
  .expert_level = 1
dataset_selection {
  use_datasets = None
    .help = "Choose a subset of datasets, based on the dataset id (as defined
"
            "              in the reflection table), to use from a"
            "multi-dataset input."
    .type = ints
    .expert_level = 2
  exclude_datasets = None
    .help = "Choose a subset of datasets, based on the dataset id (as defined
"
            "              in the reflection table), to exclude from a"
            "multi-dataset input."
    .type = ints
    .expert_level = 2
}