def main(): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks import libtbx.load_env usage = "%s [options] image_*.cbf" % ( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_datablocks_from_images=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) if len(datablocks) == 0: parser.print_help() exit() datablock = datablocks[0] imageset = datablock.extract_imagesets()[0] stability_fft(imageset, params)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections import libtbx.load_env usage = "%s [options] integrated.pickle experiments.json" % ( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=False) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if len(experiments) != 1 or len(reflections) != 1: parser.print_help() exit() if not 'shoebox' in reflections[0]: print 'Please add shoeboxes to reflection pickle' exit() results = main(reflections[0], experiments[0], params) if results: print 'mean result: %.3f' % (sum(results) / len(results))
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks import libtbx.load_env usage = "%s [options] image_*.cbf" % ( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_datablocks_from_images=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) if len(datablocks) == 0 and len(experiments) == 0 and len(reflections) == 0: parser.print_help() exit() assert(len(datablocks) == 1) datablock = datablocks[0] imagesets = datablock.extract_imagesets() assert(len(imagesets) == 1) imageset = imagesets[0] images = imageset.indices() if params.frames: images = params.frames d_spacings = [] intensities = [] sigmas = [] for indx in images: print 'For frame %d:' % indx d, I, sig = background(imageset, indx, n_bins=params.n_bins) print '%8s %8s %8s' % ('d', 'I', 'sig') for j in range(len(I)): print '%8.3f %8.3f %8.3f' % (d[j], I[j], sig[j]) d_spacings.append(d) intensities.append(I) sigmas.append(sig) if params.plot: from matplotlib import pyplot fig = pyplot.figure() for d, I, sig in zip(d_spacings, intensities, sigmas): ds2 = 1/flex.pow2(d) pyplot.plot(ds2, I) pyplot.show()
class Script(object): ''' The debugging visualization program. ''' def __init__(self): '''Initialise the script.''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] experiment.json" \ % libtbx.env.dispatcher_name # Create the parser self.parser = OptionParser( usage=usage, epilog=help_message, read_reflections=True) def run(self): from dials.util.options import flatten_reflections from dials.viewer.viewer_interface import extract_n_show # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) table = flatten_reflections(params.input.reflections) if len(table) == 0: self.parser.print_help() return extract_n_show(table[0])
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments from libtbx.utils import Sorry import libtbx.load_env usage = "%s [options] experiments.json" %libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) if len(experiments) <= 1: parser.print_help() return hkl = flex.miller_index(params.hkl) from dials.algorithms.indexing.compare_orientation_matrices import \ show_rotation_matrix_differences show_rotation_matrix_differences(experiments.crystals(), miller_indices=hkl)
def run(args): import libtbx.load_env usage = "%s [options] experiment.json indexed.pickle" % libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(reflections) == 0 or len(experiments) == 0: parser.print_help() return assert len(reflections) == 1 assert len(experiments) == 1 experiment = experiments[0] reflections = reflections[0] test_P1_crystal_indexing(reflections, experiment, params) test_crystal_pointgroup_symmetry(reflections, experiment, params)
def run(args): import libtbx.load_env from libtbx.utils import Sorry from dials.util import log usage = "%s [options] datablock.json strong.pickle" %libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=False) datablocks = flatten_datablocks(params.input.datablock) reflections = flatten_reflections(params.input.reflections) if len(datablocks) == 0 or len(reflections) == 0: parser.print_help() exit(0) # Configure the logging log.config( info=params.output.log, debug=params.output.debug_log) # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': info('The following parameters have been modified:\n') info(diff_phil) imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) assert len(imagesets) > 0 assert len(reflections) == len(imagesets) if params.scan_range is not None and len(params.scan_range) > 0: reflections = [ filter_reflections_by_scan_range(refl, params.scan_range) for refl in reflections] dps_params = dps_phil_scope.extract() # for development, we want an exhaustive plot of beam probability map: dps_params.indexing.plot_search_scope = params.plot_search_scope dps_params.indexing.mm_search_scope = params.mm_search_scope new_detector, new_beam = discover_better_experimental_model( imagesets, reflections, params, dps_params, nproc=params.nproc, wide_search_binning=params.wide_search_binning) for imageset in imagesets: imageset.set_detector(new_detector) imageset.set_beam(new_beam) from dxtbx.serialize import dump dump.datablock(datablock, params.output.datablock)
class Script(object): ''' The integration program. ''' def __init__(self): '''Initialise the script.''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] experiment.json" % libtbx.env.dispatcher_name # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, epilog=help_message, read_experiments=True) def run(self): ''' Analyse the background ''' from dials.util.command_line import heading from dials.util.options import flatten_experiments from dials.util import log from logging import info, debug from time import time from libtbx.utils import Sorry # Parse the command line params, options = self.parser.parse_args(show_diff_phil=False) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: self.parser.print_help() return assert len(experiments) == 1 # Get the imageset imageset = experiments[0].imageset total_image = None total_mask = None for i in range(len(imageset)): print i image = imageset.get_raw_data(i) mask = imageset.get_mask(i) if total_image is None: total_image = image[0] total_mask = mask[0] else: total_image += image[0] total_image /= len(imageset) print min(total_image) print max(total_image) print sum(total_image) / len(total_image) from matplotlib import pylab pylab.imshow(total_image.as_numpy_array(), vmin=0,vmax=2) pylab.show()
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments import libtbx.load_env usage = "%s [options] datablock.json" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, check_format=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) if (len(datablocks) == 0 and len(experiments) == 0): parser.print_help() exit(0) if len(datablocks) == 0 and len(experiments) > 0: imagesets = experiments.imagesets() else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) assert len(imagesets) == 1 imageset = imagesets[0] gonio = imageset.get_goniometer() if not params.detector_distance: detector = imageset.get_detector() if len(detector) > 1: params.detector_distance = detector.hierarchy().get_directed_distance() else: params.detector_distance = detector[0].get_directed_distance() if params.angle: assert len(params.angle) == len(gonio.get_angles()) else: for angle in gonio.get_angles(): params.angle.append(angle) import wxtbx.app a = wxtbx.app.CCTBXApp(0) a.settings = params f = ExperimentViewer( None, -1, "Experiment viewer", size=(1024,768)) f.load_imageset(imageset) f.Show() a.SetTopWindow(f) #a.Bind(wx.EVT_WINDOW_DESTROY, lambda evt: tb_icon.Destroy(), f) a.MainLoop()
def run(args): from dials.util import log import libtbx.load_env usage = "%s experiments.json indexed.pickle [options]" %libtbx.env.dispatcher_name from dials.util.options import OptionParser from dials.util.options import flatten_reflections from dials.util.options import flatten_experiments from dials.array_family import flex parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=False) # Configure the logging #log.config(info=params.output.log, debug=params.output.debug_log) from dials.util.version import dials_version logger.info(dials_version()) # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) assert(len(reflections) == 1) reflections = reflections[0] if len(experiments) == 0: parser.print_help() return #from dials.command_line import refine #params = refine.phil_scope.extract() indexed_reflections = reflections.select(reflections['id'] > -1) from dials.algorithms.refinement import RefinerFactory refiner = RefinerFactory.from_parameters_data_experiments( params, indexed_reflections, experiments) #refiner.run() rmsds = refiner.rmsds() import math xy_rmsds = math.sqrt(rmsds[0]**2 + rmsds[1]**2) print rmsds return
def run(args): import libtbx.load_env from libtbx.utils import Sorry from dials.util import log from logging import info import cPickle as pickle usage = "%s [options] datablock.json strong.pickle" % \ libtbx.env.dispatcher_name # Create the option parser parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_datablocks=True, check_format=False, epilog=help_message) # Get the parameters params, options = parser.parse_args(show_diff_phil=False) # Configure the log log.config( params.verbosity, info='dials.find_hot_pixels.log', debug='dials.find_hot_pixels.debug.log') # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': info('The following parameters have been modified:\n') info(diff_phil) datablocks = flatten_datablocks(params.input.datablock) reflections = flatten_reflections(params.input.reflections) if len(datablocks) == 0 and len(reflections) == 0: parser.print_help() exit(0) if len(datablocks) > 1: raise Sorry("Only one DataBlock can be processed at a time") else: imagesets = datablocks[0].extract_imagesets() if len(reflections) == 0: raise Sorry("No reflection lists found in input") if len(reflections) > 1: raise Sorry("Multiple reflections lists provided in input") assert(len(reflections) == 1) reflections = reflections[0] mask = hot_pixel_mask(imagesets[0], reflections) pickle.dump(mask, open(params.output.mask, 'w'), pickle.HIGHEST_PROTOCOL) print 'Wrote hot pixel mask to %s' % params.output.mask return
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections parser = OptionParser( phil=master_phil, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections)[0] if len(params.input.reflections) == 2: reflections2 = flatten_reflections(params.input.reflections)[1] else: reflections2 = None # find the reflections in the second set that DO NOT match those in the # first set mask, _ = reflections2.match_with_reference(reflections) reflections2 = reflections2.select(~mask) print "{0} reflections from the second set do not match the first". \ format(len(reflections2)) #reflections2 = reflections2.select(reflections2["miller_index"] == (-7,2,-25)) if len(datablocks) == 0: if len(experiments) > 0: imagesets = experiments.imagesets() else: parser.print_help() return elif len(datablocks) > 1: raise Sorry("Only one DataBlock can be processed at a time") else: imagesets = datablocks[0].extract_imagesets() if len(imagesets) > 1: raise Sorry("Only one ImageSet can be processed at a time") imageset = imagesets[0] import wxtbx.app a = wxtbx.app.CCTBXApp(0) a.settings = params f = PredRelpViewer( None, -1, "Prediction reciprocal lattice viewer", size=(1024,768)) f.load_reflections2(reflections2) f.load_models(imageset, reflections) f.Show() a.SetTopWindow(f) #a.Bind(wx.EVT_WINDOW_DESTROY, lambda evt: tb_icon.Destroy(), f) a.MainLoop()
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections import libtbx.load_env usage = "%s [options] datablock.json reflections.pickle" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0: parser.print_help() exit(0) if len(datablocks) == 0 and len(experiments) > 0: imagesets = experiments.imagesets() else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) if len(reflections) > 1: assert len(reflections) == len(imagesets) from scitbx.array_family import flex for i in range(len(reflections)): reflections[i]['imageset_id'] = flex.int(len(reflections[i]), i) if i > 0: reflections[0].extend(reflections[i]) reflections = reflections[0] import wxtbx.app a = wxtbx.app.CCTBXApp(0) a.settings = params f = ReciprocalLatticeViewer( None, -1, "Reflection data viewer", size=(1024,768)) f.load_models(imagesets, reflections) f.Show() a.SetTopWindow(f) #a.Bind(wx.EVT_WINDOW_DESTROY, lambda evt: tb_icon.Destroy(), f) a.MainLoop()
class Script(object): ''' A class to encapsulate the script. ''' def __init__(self): ''' Initialise the script. ''' from dials.util.options import OptionParser import libtbx.load_env # Create the parser usage = "usage: %s [options] datablock.json" % libtbx.env.dispatcher_name self.parser = OptionParser( usage=usage, epilog=help_message, phil=phil_scope, read_datablocks=True) def run(self): ''' Run the script. ''' from dials.util.options import flatten_datablocks from dxtbx.datablock import DataBlockDumper from libtbx.utils import Sorry import cPickle as pickle # Parse the command line arguments params, options = self.parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) # Check number of args if len(datablocks) == 0: self.parser.print_help() return # Check the mask file is given if params.input.mask is None: self.parser.print_help() return # Check nbumber of datablocks if len(datablocks) != 1: raise Sorry('exactly 1 datablock must be specified') # Get the imageset datablock = datablocks[0] imagesets = datablock.extract_imagesets() if len(imagesets) != 1: raise Sorry('datablock must contain exactly 1 imageset') imageset = imagesets[0] # Set the lookup imageset.external_lookup.mask.filename = params.input.mask # Dump the datablock print "Writing datablock to %s" % params.output.datablock dump = DataBlockDumper(datablock) dump.as_json(filename=params.output.datablock)
def run(args): import libtbx.load_env usage = "%s experiments.json [options]" %libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: parser.print_help() return elif len(experiments) > 1: raise Sorry("More than one experiment present") assert len(params.miller_index), "Must specify at least one miller_index to predict." experiment = experiments[0] reflections = flex.reflection_table() miller_indices = flex.miller_index() entering_flags = flex.bool() for mi in params.miller_index: miller_indices.append(mi) miller_indices.append(mi) entering_flags.append(True) entering_flags.append(False) reflections['miller_index'] = miller_indices reflections['entering'] = entering_flags reflections['id'] = flex.size_t(len(reflections), 0) if params.expand_to_p1: from cctbx.miller import expand_to_p1_iselection proxy = expand_to_p1_iselection( experiment.crystal.get_space_group(), anomalous_flag=True, indices=miller_indices, build_iselection=True) reflections = reflections.select(proxy.iselection) reflections['miller_index'] = proxy.indices from dials.algorithms.refinement.prediction.managed_predictors import ExperimentsPredictor predictor = ExperimentsPredictor([experiment]) predicted = predictor.predict(reflections) zmin, zmax = experiment.scan.get_array_range() z = predicted['xyzcal.px'].parts()[2] predicted = predicted.select((z >= zmin) & (z <= zmax)) show_predictions(predicted)
class Script(object): ''' A class to encapsulate the script. ''' def __init__(self): ''' Initialise the script. ''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] /path/to/image/reflection/files" % libtbx.env.dispatcher_name self.parser = OptionParser( epilog=help_message, usage=usage, phil=phil_scope, read_reflections=True) def run(self): ''' Run the script. ''' from dials.array_family import flex from dials.util.command_line import Command from libtbx.utils import Sorry # Parse the command line arguments params, options = self.parser.parse_args(show_diff_phil=True) if len(params.input.reflections) == 0: self.parser.print_help() return if len(params.input.reflections) <= 1: raise Sorry('more than 1 reflection table must be specified') tables = [p.data for p in params.input.reflections] # Get the number of rows and columns nrows = [t.nrows() for t in tables] ncols = [t.ncols() for t in tables] # Merge the reflection lists if params.method == "update": assert(all(n == nrows[0] for n in nrows[1:])) table = tables[0] for t in tables[1:]: table.update(t) elif params.method == "extend": assert(all(n == ncols[0] for n in ncols[1:])) table = tables[0] for t in tables[1:]: table.extend(t) else: raise RuntimeError('unknown method, %s' % params.method) # Write the reflections to the file Command.start('Writing %d reflections to %s' % (len(table), params.output)) table.as_pickle(params.output) Command.end('Wrote %d reflections to %s' % (len(table), params.output))
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections from dials.util import log usage = "%s [options] datablock.json reflections.pickle" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args() datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0: parser.print_help() exit(0) ## Configure the logging #log.config(info='dials.rl_png.log') # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) reflections = reflections[0] if len(datablocks) == 0 and len(experiments) > 0: imagesets = experiments.imagesets() else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) f = ReciprocalLatticeJson(settings=params) f.load_models(imagesets, reflections) f.as_json(filename=params.output.json, compact=params.output.compact) print
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments import libtbx.load_env usage = "%s [options] datablock.json | experiments.json" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) datablocks = flatten_datablocks(params.input.datablock) if len(experiments) == 0 and len(datablocks) == 0: parser.print_help() exit(0) from dials.command_line.dials_import import ManualGeometryUpdater update_geometry = ManualGeometryUpdater(params) if len(experiments): imagesets = experiments.imagesets() elif len(datablocks): assert len(datablocks) == 1 imagesets = datablocks[0].extract_imageset() for imageset in imagesets: imageset_new = update_geometry(imageset) imageset.set_detector(imageset_new.get_detector()) imageset.set_beam(imageset_new.get_beam()) imageset.set_goniometer(imageset_new.get_goniometer()) imageset.set_scan(imageset_new.get_scan()) from dxtbx.serialize import dump if len(experiments): print "Saving modified experiments to %s" %params.output.experiments dump.experiment_list(experiments, params.output.experiments) elif len(datablocks): raise NotImplemented
def run(args): import libtbx.load_env from dials.array_family import flex from dials.util import log from dials.util.version import dials_version usage = "%s [options] experiment.json indexed.pickle" % \ libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) # Configure the logging log.config(info=params.output.log, debug=params.output.debug_log) logger.info(dials_version()) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(reflections) == 0 or len(experiments) == 0: parser.print_help() return assert(len(reflections) == 1) assert(len(experiments) == 1) experiment = experiments[0] reflections = reflections[0] # remove reflections with 0, 0, 0 index zero = (reflections['miller_index'] == (0, 0, 0)) logger.info('Removing %d unindexed reflections' % zero.count(True)) reflections = reflections.select(~zero) h, k, l = reflections['miller_index'].as_vec3_double().parts() h = h.iround() k = k.iround() l = l.iround() logger.info('Range on h: %d to %d' % (flex.min(h), flex.max(h))) logger.info('Range on k: %d to %d' % (flex.min(k), flex.max(k))) logger.info('Range on l: %d to %d' % (flex.min(l), flex.max(l))) test_P1_crystal_indexing(reflections, experiment, params) test_crystal_pointgroup_symmetry(reflections, experiment, params)
class Script(object): ''' A class to encapsulate the script. ''' def __init__(self): ''' Initialise the script. ''' from dials.util.options import OptionParser import libtbx.load_env # Create the parser usage = "usage: %s [options] reflections.pickle" % libtbx.env.dispatcher_name self.parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, epilog=help_message) self.parser.add_option( '--xkcd', action='store_true', dest='xkcd', default=False, help='Special drawing mode') def run(self): ''' Run the script. ''' from dials.util.command_line import Command from libtbx.utils import Sorry # Parse the command line arguments params, options = self.parser.parse_args(show_diff_phil=True) if options.xkcd: from matplotlib import pyplot pyplot.xkcd() # Shoe the help if len(params.input.reflections) != 1: self.parser.print_help() exit(0) # Analyse the reflections analyse = Analyser( params.output.directory, grid_size=params.grid_size, pixels_per_bin=params.pixels_per_bin, centroid_diff_max=params.centroid_diff_max) analyse(params.input.reflections[0].data)
def run(args): import libtbx.load_env usage = """\ %s datablock.json reflections.pickle [options]""" %libtbx.env.dispatcher_name from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections from scitbx.array_family import flex from scitbx import matrix from libtbx.phil import command_line from libtbx.utils import Sorry parser = OptionParser( usage=usage, phil=master_phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(datablocks) == 1: imageset = datablocks[0].extract_imagesets()[0] elif len(datablocks) > 1: raise Sorry("Only one DataBlock can be processed at a time") elif len(experiments.imagesets()) > 0: imageset = experiments.imagesets()[0] imageset.set_detector(experiments[0].detector) imageset.set_beam(experiments[0].beam) imageset.set_goniometer(experiments[0].goniometer) else: parser.print_help() return detector = imageset.get_detector() scan = imageset.get_scan() panel_origin_shifts = {0: (0,0,0)} try: hierarchy = detector.hierarchy() except AttributeError, e: hierarchy = None
def run(args): import libtbx.load_env from libtbx.utils import Sorry usage = "%s [options] datablock.json" %libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, check_format=True, read_datablocks_from_images=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=False) ## Configure the logging #log.config( #params.verbosity, info='dials.estimate_gain.log', debug='dials.estimate_gain.debug.log') # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': print 'The following parameters have been modified:\n' print diff_phil datablocks = flatten_datablocks(params.input.datablock) if len(datablocks) == 0: parser.print_help() return elif len(datablocks) > 1: raise Sorry("Only one DataBlock can be processed at a time") else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) assert len(imagesets) == 1 imageset = imagesets[0] estimate_gain(imageset, params.kernel_size, params.output.gain_map) return
class Script(object): '''A class for running the script.''' def __init__(self): '''Initialise the script.''' from dials.util.options import OptionParser from libtbx.phil import parse import libtbx.load_env # The script usage usage = "usage: %s [options] experiment_one.json experiment_two.json" \ % libtbx.env.dispatcher_name # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, epilog=help_message, check_format=False, read_experiments=True) def run(self): '''Execute the script.''' from dials.util.command_line import Command from dials.array_family import flex from dials.util.options import flatten_experiments # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) # Check the number of experiments is at least 2 experiments = flatten_experiments(params.input.experiments) if len(experiments) < 2: self.parser.print_help() return detectors = [experiment.detector[0] for experiment in experiments] from itertools import combinations for pair in combinations(detectors, 2): determine_axis(pair, params)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks import libtbx.load_env usage = "%s [options] datablock.json" % ( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_datablocks_from_images=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) if len(datablocks) == 0: parser.print_help() exit() assert(len(datablocks) == 1) datablock = datablocks[0] imagesets = datablock.extract_imagesets() assert(len(imagesets) == 1) imageset = imagesets[0] images = params.image for j, img_a in enumerate(images[:-1]): for img_b in images[j+1:]: a = imageset.get_raw_data(img_a)[0] b = imageset.get_raw_data(img_b)[0] n, cc = image_correlation(a, b) print '%5d %5d %7d %.4f' % (img_a, img_b, n, cc)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections import libtbx.load_env usage = "%s [options] datablock.json reflections.pickle" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0: parser.print_help() exit(0) reflections = reflections[0] if len(datablocks) == 0 and len(experiments) > 0: imagesets = experiments.imagesets() else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) spot_resolution_shells(imagesets, reflections, params)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections import libtbx.load_env from dials.util import best usage = "%s [options] experiments.json integrated.pickle" % ( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if len(experiments) == 0 or len(reflections) == 0: parser.print_help() exit() #assert(len(experiments) == 1) experiment = experiments[0] reflections = reflections[0] imageset = experiment.imageset best.write_background_file('bestfile.dat', imageset, n_bins=params.n_bins) best.write_integrated_hkl('bestfile', reflections) best.write_par_file('bestfile.par', experiment)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks import libtbx.load_env usage = "%s [options] datablock.json reference=reference_datablock.json" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) if len(datablocks) == 0: parser.print_help() exit() # Load reference geometry reference_detector = None if params.input.reference is not None: from dxtbx.serialize import load try: reference_experiments = load.experiment_list( params.input.reference, check_format=False) assert len(reference_experiments.detectors()) == 1 reference_detector = reference_experiments.detectors()[0] except Exception, e: reference_datablocks = load.datablock(params.input.reference) assert len(reference_datablocks) == 1 imageset = reference_datablocks[0].extract_imagesets()[0] reference_detector = imageset.get_detector()
def run(): import sys import libtbx.load_env from dials.util.options import OptionParser from dials.util.options import flatten_datablocks usage = "%s [options] image_*.cbf" %libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_datablocks=True, read_datablocks_from_images=True, epilog=help_message ) params, options, args = parser.parse_args( show_diff_phil=True, return_unhandled=True) n_images = params.merge_n_images out_prefix = params.output.image_prefix datablocks = flatten_datablocks(params.input.datablock) if len(datablocks) == 0: parser.print_help() return if len(datablocks) > 1: raise Sorry("Only one DataBlock can be processed at a time") else: imagesets = datablocks[0].extract_imagesets() assert len(imagesets) == 1 imageset = imagesets[0] merge_cbf(imageset, n_images, out_prefix=out_prefix)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments usage = "dials.background [options] image_*.cbf" parser = OptionParser(usage=usage, phil=phil_scope, read_experiments=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) # Ensure we have either a data block or an experiment list experiments = flatten_experiments(params.input.experiments) if len(experiments) != 1: parser.print_help() return imagesets = experiments.imagesets() if len(imagesets) != 1: raise Sorry( "Please pass an experiment list that contains a single imageset") imageset = imagesets[0] first, last = imageset.get_scan().get_image_range() images = range(first, last + 1) if params.images: if min(params.images) < first or max(params.images) > last: raise Sorry("image outside of scan range") images = params.images d_spacings = [] intensities = [] sigmas = [] for indx in images: print("For image %d:" % indx) indx -= first # indices passed to imageset.get_raw_data start from zero d, I, sig = background( imageset, indx, n_bins=params.n_bins, corrected=params.corrected, mask_params=params.masking, ) print("%8s %8s %8s" % ("d", "I", "sig")) for j in range(len(I)): print("%8.3f %8.3f %8.3f" % (d[j], I[j], sig[j])) d_spacings.append(d) intensities.append(I) sigmas.append(sig) if params.plot: from matplotlib import pyplot fig = pyplot.figure() ax = fig.add_subplot(111) ax.set_xlabel(r"resolution ($\AA$)") ax.set_ylabel(r"$\langle I_b \rangle$") for d, I, sig in zip(d_spacings, intensities, sigmas): ds2 = 1 / flex.pow2(d) ax.plot(ds2, I) xticks = ax.get_xticks() x_tick_labs = [ "" if e <= 0.0 else "{:.2f}".format(math.sqrt(1.0 / e)) for e in xticks ] ax.set_xticklabels(x_tick_labs) pyplot.show()
def run(args=None): import libtbx.load_env from dials.util import Sorry usage = "dials.reindex [options] indexed.expt indexed.refl" parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(args, show_diff_phil=True) reflections, experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments) if len(experiments) == 0 and len(reflections) == 0: parser.print_help() return if params.change_of_basis_op is None: raise Sorry("Please provide a change_of_basis_op.") reference_crystal = None if params.reference.experiments is not None: from dxtbx.serialize import load reference_experiments = load.experiment_list( params.reference.experiments, check_format=False) assert len(reference_experiments.crystals()) == 1 reference_crystal = reference_experiments.crystals()[0] if params.reference.reflections is not None: # First check that we have everything as expected for the reference reindexing # Currently only supports reindexing one dataset at a time if params.reference.experiments is None: raise Sorry( """For reindexing against a reference dataset, a reference experiments file must also be specified with the option: reference= """) if not os.path.exists(params.reference.reflections): raise Sorry("Could not locate reference dataset reflection file") if len(experiments) != 1 or len(reflections) != 1: raise Sorry( "Only one dataset can be reindexed to a reference at a time") reference_reflections = flex.reflection_table().from_file( params.reference.reflections) test_reflections = reflections[0] if (reference_crystal.get_space_group().type().number() != experiments.crystals()[0].get_space_group().type().number()): raise Sorry("Space group of input does not match reference") # Set some flags to allow filtering, if wanting to reindex against # reference with data that has not yet been through integration if (test_reflections.get_flags( test_reflections.flags.integrated_sum).count(True) == 0): assert ( "intensity.sum.value" in test_reflections), "No 'intensity.sum.value' in reflections" test_reflections.set_flags( flex.bool(test_reflections.size(), True), test_reflections.flags.integrated_sum, ) if (reference_reflections.get_flags( reference_reflections.flags.integrated_sum).count(True) == 0): assert ("intensity.sum.value" in test_reflections ), "No 'intensity.sum.value in reference reflections" reference_reflections.set_flags( flex.bool(reference_reflections.size(), True), reference_reflections.flags.integrated_sum, ) # Make miller array of the two datasets try: test_miller_set = filtered_arrays_from_experiments_reflections( experiments, [test_reflections])[0] except ValueError: raise Sorry( "No reflections remain after filtering the test dataset") try: reference_miller_set = filtered_arrays_from_experiments_reflections( reference_experiments, [reference_reflections])[0] except ValueError: raise Sorry( "No reflections remain after filtering the reference dataset") from dials.algorithms.symmetry.reindex_to_reference import ( determine_reindex_operator_against_reference, ) change_of_basis_op = determine_reindex_operator_against_reference( test_miller_set, reference_miller_set) elif len(experiments) and params.change_of_basis_op is libtbx.Auto: if reference_crystal is not None: if len(experiments.crystals()) > 1: raise Sorry("Only one crystal can be processed at a time") from dials.algorithms.indexing.compare_orientation_matrices import ( difference_rotation_matrix_axis_angle, ) cryst = experiments.crystals()[0] R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle( cryst, reference_crystal) print(f"Change of basis op: {change_of_basis_op}") print("Rotation matrix to transform input crystal to reference::") print(R.mathematica_form(format="%.3f", one_row_per_line=True)) print( f"Rotation of {angle:.3f} degrees", "about axis (%.3f, %.3f, %.3f)" % axis, ) elif len(reflections): assert len(reflections) == 1 # always re-map reflections to reciprocal space refl = reflections.deep_copy() refl.centroid_px_to_mm(experiments) refl.map_centroids_to_reciprocal_space(experiments) # index the reflection list using the input experiments list refl["id"] = flex.int(len(refl), -1) index = AssignIndicesGlobal(tolerance=0.2) index(refl, experiments) hkl_expt = refl["miller_index"] hkl_input = reflections[0]["miller_index"] change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt) # reset experiments list since we don't want to reindex this experiments = [] else: change_of_basis_op = sgtbx.change_of_basis_op( params.change_of_basis_op) if len(experiments): space_group = params.space_group if space_group is not None: space_group = space_group.group() try: experiments = reindex_experiments(experiments, change_of_basis_op, space_group=space_group) except RuntimeError as e: # Only catch specific errors here if "Unsuitable value for rational rotation matrix." in str(e): original_message = str(e).split(":")[-1].strip() sys.exit( f"Error: {original_message} Is your change_of_basis_op valid?" ) raise print( f"Saving reindexed experimental models to {params.output.experiments}" ) experiments.as_file(params.output.experiments) if len(reflections): assert len(reflections) == 1 reflections = reflections[0] miller_indices = reflections["miller_index"] if params.hkl_offset is not None: h, k, l = miller_indices.as_vec3_double().parts() h += params.hkl_offset[0] k += params.hkl_offset[1] l += params.hkl_offset[2] miller_indices = flex.miller_index(h.iround(), k.iround(), l.iround()) non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices( miller_indices) if non_integral_indices.size() > 0: print( "Removing %i/%i reflections (change of basis results in non-integral indices)" % (non_integral_indices.size(), miller_indices.size())) sel = flex.bool(miller_indices.size(), True) sel.set_selected(non_integral_indices, False) miller_indices_reindexed = change_of_basis_op.apply( miller_indices.select(sel)) reflections["miller_index"].set_selected(sel, miller_indices_reindexed) reflections["miller_index"].set_selected(~sel, (0, 0, 0)) print(f"Saving reindexed reflections to {params.output.reflections}") reflections.as_file(params.output.reflections)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments import libtbx.load_env usage = "%s [options] datablock.json" % (libtbx.env.dispatcher_name) parser = OptionParser(usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: parser.print_help() exit(0) imagesets = experiments.imagesets() predicted_all = None dose = flex.size_t() for i_expt, expt in enumerate(experiments): if params.space_group is not None: expt.crystal.set_space_group(params.space_group.group()) strategy = Strategy(expt, d_min=params.d_min, unit_cell_scale=params.unit_cell_scale, degrees_per_bin=params.degrees_per_bin, min_frac_new=params.minimum_fraction_new) strategy.plot(prefix='strategy1_') expt2 = copy.deepcopy(expt) scan = expt2.scan gonio = expt2.goniometer angles = gonio.get_angles() theta_max = strategy.theta_max fixed_rotation = matrix.sqr(gonio.get_fixed_rotation()) setting_rotation = matrix.sqr(gonio.get_setting_rotation()) rotation_axis = matrix.col(gonio.get_rotation_axis_datum()) rotation_matrix = rotation_axis.axis_and_angle_as_r3_rotation_matrix( scan.get_oscillation()[0], deg=True) D_p = (setting_rotation * rotation_matrix * fixed_rotation) beam = expt2.beam s0 = matrix.col(beam.get_unit_s0()) # rotate crystal by at least 2 * theta_max around axis perpendicular to # goniometer rotation axis n = rotation_axis.cross(s0) solutions = flex.vec3_double() rotation_angles = flex.double() for sign in (1, -1): i = 0 while True: rot_angle = 2 * sign * (theta_max + i) i += 1 R = n.axis_and_angle_as_r3_rotation_matrix(rot_angle, deg=True) axes = gonio.get_axes() assert len(axes) == 3 e1, e2, e3 = (matrix.col(e) for e in reversed(axes)) from dials.algorithms.refinement import rotation_decomposition solns = rotation_decomposition.solve_r3_rotation_for_angles_given_axes( R * D_p, e1, e2, e3, return_both_solutions=True, deg=True) if solns is not None: solutions.extend(flex.vec3_double(solns)) for i in range(len(solns)): rotation_angles.append(rot_angle) break for rot_angle, solution in zip(rotation_angles, solutions): angles = reversed(solution) gonio.set_angles(angles) print print "Goniometer settings to rotate crystal by %.2f degrees:" % rot_angle for name, angle in zip(gonio.get_names(), gonio.get_angles()): print "%s: %.2f degrees" % (name, angle) print strategy2 = Strategy(expt2, d_min=params.d_min, unit_cell_scale=params.unit_cell_scale, degrees_per_bin=params.degrees_per_bin, min_frac_new=params.minimum_fraction_new) strategy2.plot(prefix='strategy2_') stats = ComputeStats([strategy, strategy2]) stats.show() plot_statistics(stats, prefix='multi_strategy_') return
class Script(object): ''' Encapsulate the script in a class. ''' def __init__(self): ''' Initialise the script. ''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] experiments.json spots.pickle" \ % libtbx.env.dispatcher_name self.parser = OptionParser(usage=usage, epilog=help_message, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False) def run(self): ''' Run the script. ''' from dials.algorithms.profile_model.factory import ProfileModelFactory from dials.util.command_line import Command from dials.array_family import flex from dials.util.options import flatten_reflections, flatten_experiments from dxtbx.model.experiment_list import ExperimentListDumper from libtbx.utils import Sorry from dials.util import log log.config() # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(reflections) == 0 and len(experiments) == 0: self.parser.print_help() return if len(reflections) != 1: raise Sorry('exactly 1 reflection table must be specified') if len(experiments) == 0: raise Sorry('no experiments were specified') if (not 'background.mean' in reflections[0]) and params.subtract_background: raise Sorry( 'for subtract_background need background.mean in reflections') reflections, _ = self.process_reference(reflections[0], params) # Check pixels don't belong to neighbours self.filter_reference_pixels(reflections, experiments) # Predict the reflections logger.info("") logger.info("=" * 80) logger.info("") logger.info("Predicting reflections") logger.info("") predicted = flex.reflection_table.from_predictions_multi( experiments, dmin=params.prediction.d_min, dmax=params.prediction.d_max, margin=params.prediction.margin, force_static=params.prediction.force_static, padding=params.prediction.padding) # Match with predicted matched, reflections, unmatched = predicted.match_with_reference( reflections) assert (len(matched) == len(predicted)) assert (matched.count(True) <= len(reflections)) if matched.count(True) == 0: raise Sorry(''' Invalid input for reference reflections. Zero reference spots were matched to predictions ''') elif len(unmatched) != 0: logger.info('') logger.info('*' * 80) logger.info( 'Warning: %d reference spots were not matched to predictions' % (len(unmatched))) logger.info('*' * 80) logger.info('') # Create the profile model experiments = ProfileModelFactory.create(params, experiments, reflections) for model in experiments: sigma_b = model.profile.sigma_b(deg=True) sigma_m = model.profile.sigma_m(deg=True) if type(sigma_b) == type(1.0): logger.info('Sigma B: %f' % sigma_b) logger.info('Sigma M: %f' % sigma_m) else: # scan varying mean_sigma_b = sum(sigma_b) / len(sigma_b) mean_sigma_m = sum(sigma_m) / len(sigma_m) logger.info('Sigma B: %f' % mean_sigma_b) logger.info('Sigma M: %f' % mean_sigma_m) # Wrtie the parameters Command.start("Writing experiments to %s" % params.output) dump = ExperimentListDumper(experiments) with open(params.output, "w") as outfile: outfile.write(dump.as_json()) Command.end("Wrote experiments to %s" % params.output) def process_reference(self, reference, params): ''' Load the reference spots. ''' from dials.array_family import flex from time import time from libtbx.utils import Sorry if reference is None: return None, None st = time() assert ("miller_index" in reference) assert ("id" in reference) logger.info('Processing reference reflections') logger.info(' read %d strong spots' % len(reference)) mask = reference.get_flags(reference.flags.indexed) rubbish = reference.select(mask == False) if mask.count(False) > 0: reference.del_selected(mask == False) logger.info(' removing %d unindexed reflections' % mask.count(False)) if len(reference) == 0: raise Sorry(''' Invalid input for reference reflections. Expected > %d indexed spots, got %d ''' % (0, len(reference))) mask = reference.get_flags(reference.flags.centroid_outlier) if mask.count(True) > 0: rubbish.extend(reference.select(mask)) reference.del_selected(mask) logger.info( ' removing %d reflections marked as centroid outliers' % mask.count(True)) mask = reference['miller_index'] == (0, 0, 0) if mask.count(True) > 0: rubbish.extend(reference.select(mask)) reference.del_selected(mask) logger.info(' removing %d reflections with hkl (0,0,0)' % mask.count(True)) mask = reference['id'] < 0 if mask.count(True) > 0: raise Sorry(''' Invalid input for reference reflections. %d reference spots have an invalid experiment id ''' % mask.count(True)) logger.info(' using %d indexed reflections' % len(reference)) logger.info(' found %d junk reflections' % len(rubbish)) from dials.array_family import flex if 'background.mean' in reference and params.subtract_background: logger.info( ' subtracting background from %d reference reflections' % len(reference)) for spot in reference: spot['shoebox'].data -= spot['background.mean'] logger.info(' time taken: %g' % (time() - st)) return reference, rubbish def filter_reference_pixels(self, reference, experiments): ''' Set any pixel closer to other reflections to background ''' modified_count = 0 for experiment, indices in reference.iterate_experiments_and_indices( experiments): subset = reference.select(indices) modified = subset['shoebox'].mask_neighbouring( subset['miller_index'], experiment.beam, experiment.detector, experiment.goniometer, experiment.scan, experiment.crystal) modified_count += modified.count(True) reference.set_selected(indices, subset) logger.info(" masked neighbouring pixels in %d shoeboxes" % modified_count) return reference
class Script(object): """The integration program.""" def __init__(self): """Initialise the script.""" from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: dev.dials.make_polar_background_image [options] models.expt" # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, epilog=help_message, read_experiments=True ) def run(self): """Perform the integration.""" from dials.util.options import flatten_experiments from dials.util import log from dials.array_family import flex # Parse the command line params, options = self.parser.parse_args(show_diff_phil=False) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: self.parser.print_help() return assert len(experiments) == 1 imageset = experiments[0].imageset beam = experiments[0].beam detector = experiments[0].detector goniometer = experiments[0].goniometer assert len(detector) == 1 # Configure logging log.config() from dials.algorithms.background.gmodel import PolarTransform import six.moves.cPickle as pickle with open(params.model, "rb") as fh: model = pickle.load(fh) image = model.data(0) mask = flex.bool(image.accessor(), True) # Do the transformation transform = PolarTransform(beam, detector[0], goniometer) result = transform.to_polar(image, mask) data = result.data() mask = result.mask() with open(params.output.data, "wb") as fh: pickle.dump((data, mask), fh, pickle.HIGHEST_PROTOCOL) from matplotlib import pylab vmax = sorted(list(data))[int(0.99 * len(data))] figure = pylab.figure(figsize=(6, 4)) pylab.imshow(data.as_numpy_array(), interpolation="none", vmin=0, vmax=vmax) ax1 = pylab.gca() ax1.get_xaxis().set_visible(False) ax1.get_yaxis().set_visible(False) cb = pylab.colorbar() cb.ax.tick_params(labelsize=8) logger.info("Saving polar model %s" % (params.output.image)) pylab.savefig("%s" % (params.output.image), dpi=600, bbox_inches="tight")
%s datablock.json [reflections.pickle] """ % libtbx.env.dispatcher_name parser = OptionParser(usage=usage_message, phil=phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, read_datablocks_from_images=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if len(datablocks) == 0 and len(experiments) == 0: parser.print_help() exit(0) if len(datablocks) > 0: assert len(datablocks) == 1 datablock = datablocks[0] else: datablock = None if params.mask is not None: from libtbx import easy_pickle params.mask = easy_pickle.load(params.mask) runner = Script(params=params, reflections=reflections, datablock=datablock,
class Script(object): """A class for running the script.""" def __init__(self): """Initialise the script.""" from libtbx.phil import parse # The phil scope phil_scope = parse( """ scale = unit *max_cell ewald_sphere_radius .type = choice .help = "Choose the scale for the direction vector in orthogonal" "coordinates prior to transformation into fractional" "coordinates [uvw]" plot_filename = None .type = str .help = "Filename for a plot of angle between neighbouring frames" "(set to None for no plot)" """, process_includes=True, ) usage = "dials.frame_orientations refined.expt refined.refl" # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=__doc__, ) def run(self): """Execute the script.""" # Parse the command line self.params, _ = self.parser.parse_args(show_diff_phil=True) if not self.params.input.experiments: self.parser.print_help() sys.exit() # Try to load the models experiments = flatten_experiments(self.params.input.experiments) nexp = len(experiments) if nexp == 0: self.parser.print_help() sys.exit("No Experiments found in the input") # Set up a plot if requested if self.params.plot_filename: plt.figure() header = [ "Image", "Beam direction (xyz)", "Zone axis [uvw]", "Angles between beam\nand axes a, b, c (deg)", "Angle from\nprevious image (deg)", ] for iexp, exp in enumerate(experiments): print("For Experiment id = {}".format(iexp)) print(exp.beam) print(exp.crystal) print(exp.scan) if self.params.scale == "ewald_sphere_radius": scale = 1.0 / exp.beam.get_wavelength() elif self.params.scale == "max_cell": uc = exp.crystal.get_unit_cell() scale = max(uc.parameters()[0:3]) else: scale = 1.0 print("Beam direction scaled by {0} = {1:.3f} to " "calculate zone axis\n".format(self.params.scale, scale)) dat = extract_experiment_data(exp, scale) images = dat["images"] directions = dat["directions"] zone_axes = dat["zone_axes"] real_space_axes = dat["real_space_axes"] # calculate the angle between the beam and each crystal axis axis_angles = [] for d, rsa in zip(directions, real_space_axes): angles = [d.angle(a, deg=True) for a in rsa] axis_angles.append("{:.2f} {:.2f} {:.2f}".format(*angles)) # calculate the orientation offset between each image offset = [ e1.angle(e2, deg=True) for e1, e2 in zip(zone_axes[:-1], zone_axes[1:]) ] str_off = ["---"] + ["{:.8f}".format(e) for e in offset] rows = [] for i, d, z, a, o in zip( images, directions, zone_axes, axis_angles, str_off, ): row = [ str(i), "{:.8f} {:.8f} {:.8f}".format(*d.elems), "{:.8f} {:.8f} {:.8f}".format(*z.elems), a, o, ] rows.append(row) # Print the table print(tabulate(rows, header)) # Add to the plot, if requested if self.params.plot_filename: plt.scatter(images[1:], offset, s=1) # Finish and save plot, if requested if self.params.plot_filename: plt.xlabel("Image number") plt.ylabel(r"Angle from previous image $\left(^\circ\right)$") plt.title(r"Angle between neighbouring images") print("Saving plot to {}".format(self.params.plot_filename)) plt.savefig(self.params.plot_filename) print()
class Script(object): '''A class for running the script.''' def __init__(self): '''Initialise the script.''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] [param.phil] "\ "datablock.json" \ % libtbx.env.dispatcher_name # Initialise the base class self.parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message, read_datablocks=True, read_reflections=True) def run(self): '''Execute the script.''' from dials.array_family import flex from dials.util.options import flatten_datablocks from dials.util.options import flatten_reflections from time import time from dials.util import log from libtbx.utils import Sorry start_time = time() # Parse the command line params, options = self.parser.parse_args(show_diff_phil=False) # Configure the logging log.config(params.verbosity, info=params.output.log, debug=params.output.debug_log) from dials.util.version import dials_version logger.info(dials_version()) # Log the diff phil diff_phil = self.parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) # Ensure we have a data block datablocks = flatten_datablocks(params.input.datablock) reflections = flatten_reflections(params.input.reflections) if len(datablocks) == 0 and len(reflections) == 0: self.parser.print_help() return elif len(datablocks) != len(reflections): raise Sorry( "Must have same number of datablocks and reflection tables") # Combine the datablocks and reflections datablock, reflections = combine(datablocks, reflections, params) # Save the reflections to file logger.info('\n' + '-' * 80) reflections.as_pickle(params.output.reflections) logger.info('Saved {0} reflections to {1}'.format( len(reflections), params.output.reflections)) # Save the datablock from dxtbx.datablock import DataBlockDumper logger.info('Saving datablocks to {0}'.format(params.output.datablock)) dump = DataBlockDumper(datablocks) dump.as_file(params.output.datablock) # Print the time logger.info("Time Taken: %f" % (time() - start_time))
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments from dials.util.options import flatten_datablocks from dials.util.options import flatten_reflections import libtbx.load_env usage = "%s [options] datablock.json | experiments.json | image_*.cbf" % ( libtbx.env.dispatcher_name) parser = OptionParser(usage=usage, phil=phil_scope, read_experiments=True, read_datablocks=True, read_datablocks_from_images=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) datablocks = flatten_datablocks(params.input.datablock) reflections = flatten_reflections(params.input.reflections) if len(datablocks) == 0 and len(experiments) == 0 and len( reflections) == 0: parser.print_help() exit() for i_expt, expt in enumerate(experiments): print "Experiment %i:" % i_expt print str(expt.detector) print 'Max resolution (at corners): %f' % ( expt.detector.get_max_resolution(expt.beam.get_s0())) print 'Max resolution (inscribed): %f' % ( expt.detector.get_max_inscribed_resolution(expt.beam.get_s0())) if params.show_panel_distance: for ipanel, panel in enumerate(expt.detector): from scitbx import matrix fast = matrix.col(panel.get_fast_axis()) slow = matrix.col(panel.get_slow_axis()) normal = fast.cross(slow).normalize() origin = matrix.col(panel.get_origin()) distance = origin.dot(normal) fast_origin = -(origin - distance * normal).dot(fast) slow_origin = -(origin - distance * normal).dot(slow) print 'Panel %d: distance %.2f origin %.2f %.2f' % \ (ipanel, distance, fast_origin, slow_origin) print '' print '' print show_beam(expt.detector, expt.beam) if expt.scan is not None: print expt.scan if expt.goniometer is not None: print expt.goniometer expt.crystal.show(show_scan_varying=params.show_scan_varying) if expt.crystal.num_scan_points: from scitbx.array_family import flex from cctbx import uctbx abc = flex.vec3_double() angles = flex.vec3_double() for n in range(expt.crystal.num_scan_points): a, b, c, alpha, beta, gamma = expt.crystal.get_unit_cell_at_scan_point( n).parameters() abc.append((a, b, c)) angles.append((alpha, beta, gamma)) a, b, c = abc.mean() alpha, beta, gamma = angles.mean() mean_unit_cell = uctbx.unit_cell((a, b, c, alpha, beta, gamma)) print " Average unit cell: %s" % mean_unit_cell print if expt.profile is not None: print expt.profile for datablock in datablocks: if datablock.format_class() is not None: print 'Format: %s' % datablock.format_class() imagesets = datablock.extract_imagesets() for imageset in imagesets: try: print imageset.get_template() except Exception: pass detector = imageset.get_detector() print str(detector) print 'Max resolution (at corners): %f' % ( detector.get_max_resolution(imageset.get_beam().get_s0())) print 'Max resolution (inscribed): %f' % ( detector.get_max_inscribed_resolution( imageset.get_beam().get_s0())) if params.show_panel_distance: for ipanel, panel in enumerate(detector): from scitbx import matrix fast = matrix.col(panel.get_fast_axis()) slow = matrix.col(panel.get_slow_axis()) normal = fast.cross(slow) origin = matrix.col(panel.get_origin()) distance = origin.dot(normal) fast_origin = -(origin - distance * normal).dot(fast) slow_origin = -(origin - distance * normal).dot(slow) print 'Panel %d: distance %.2f origin %.2f %.2f' % \ (ipanel, distance, fast_origin, slow_origin) print '' print '' print show_beam(detector, imageset.get_beam()) if imageset.get_scan() is not None: print imageset.get_scan() if imageset.get_goniometer() is not None: print imageset.get_goniometer() from libtbx.containers import OrderedDict, OrderedSet formats = OrderedDict([ ('miller_index', '%i, %i, %i'), ('d', '%.2f'), ('dqe', '%.3f'), ('id', '%i'), ('imageset_id', '%i'), ('panel', '%i'), ('flags', '%i'), ('background.mean', '%.1f'), ('background.dispersion', '%.1f'), ('background.mse', '%.1f'), ('background.sum.value', '%.1f'), ('background.sum.variance', '%.1f'), ('intensity.prf.value', '%.1f'), ('intensity.prf.variance', '%.1f'), ('intensity.sum.value', '%.1f'), ('intensity.sum.variance', '%.1f'), ('intensity.cor.value', '%.1f'), ('intensity.cor.variance', '%.1f'), ('lp', '%.3f'), ('num_pixels.background', '%i'), ('num_pixels.background_used', '%i'), ('num_pixels.foreground', '%i'), ('num_pixels.valid', '%i'), ('partial_id', '%i'), ('partiality', '%.4f'), ('profile.correlation', '%.3f'), ('profile.rmsd', '%.3f'), ('xyzcal.mm', '%.2f, %.2f, %.2f'), ('xyzcal.px', '%.2f, %.2f, %.2f'), ('delpsical.rad', '%.3f'), ('delpsical2', '%.3f'), ('delpsical.weights', '%.3f'), ('xyzobs.mm.value', '%.2f, %.2f, %.2f'), ('xyzobs.mm.variance', '%.4e, %.4e, %.4e'), ('xyzobs.px.value', '%.2f, %.2f, %.2f'), ('xyzobs.px.variance', '%.4f, %.4f, %.4f'), ('s1', '%.4f, %.4f, %.4f'), ('rlp', '%.4f, %.4f, %.4f'), ('zeta', '%.3f'), ('x_resid', '%.3f'), ('x_resid2', '%.3f'), ('y_resid', '%.3f'), ('y_resid2', '%.3f'), ('kapton_absorption_correction', '%.3f'), ('kapton_absorption_correction_sigmas', '%.3f'), ]) for rlist in reflections: from cctbx.array_family import flex print print "Reflection list contains %i reflections" % (len(rlist)) if len(rlist) == 0: continue rows = [["Column", "min", "max", "mean"]] for k, col in rlist.cols(): if type(col) in (flex.double, flex.int, flex.size_t): if type(col) in (flex.int, flex.size_t): col = col.as_double() rows.append([ k, formats[k] % flex.min(col), formats[k] % flex.max(col), formats[k] % flex.mean(col) ]) elif type(col) in (flex.vec3_double, flex.miller_index): if type(col) == flex.miller_index: col = col.as_vec3_double() rows.append([ k, formats[k] % col.min(), formats[k] % col.max(), formats[k] % col.mean() ]) from libtbx import table_utils print table_utils.format(rows, has_header=True, prefix="| ", postfix=" |") intensity_keys = ('miller_index', 'd', 'intensity.prf.value', 'intensity.prf.variance', 'intensity.sum.value', 'intensity.sum.variance', 'background.mean', 'profile.correlation', 'profile.rmsd') profile_fit_keys = ( 'miller_index', 'd', ) centroid_keys = ('miller_index', 'd', 'xyzcal.mm', 'xyzcal.px', 'xyzobs.mm.value', 'xyzobs.mm.variance', 'xyzobs.px.value', 'xyzobs.px.variance') keys_to_print = OrderedSet() if params.show_intensities: for k in intensity_keys: keys_to_print.add(k) if params.show_profile_fit: for k in profile_fit_keys: keys_to_print.add(k) if params.show_centroids: for k in centroid_keys: keys_to_print.add(k) if params.show_all_reflection_data: for k in formats: keys_to_print.add(k) def format_column(key, data, format_strings=None): if isinstance(data, flex.vec3_double): c_strings = [ c.as_string(format_strings[i].strip()) for i, c in enumerate(data.parts()) ] elif isinstance(data, flex.miller_index): c_strings = [ c.as_string(format_strings[i].strip()) for i, c in enumerate(data.as_vec3_double().parts()) ] elif isinstance(data, flex.size_t): c_strings = [data.as_int().as_string(format_strings[0].strip())] else: c_strings = [data.as_string(format_strings[0].strip())] column = flex.std_string() max_element_lengths = [c.max_element_length() for c in c_strings] for i in range(len(c_strings[0])): column.append(('%%%is' % len(key)) % ', '.join( ('%%%is' % max_element_lengths[j]) % c_strings[j][i] for j in range(len(c_strings)))) return column if keys_to_print: keys = [k for k in keys_to_print if k in rlist] rows = [keys] max_reflections = len(rlist) if params.max_reflections is not None: max_reflections = min(len(rlist), params.max_reflections) columns = [] for k in keys: columns.append( format_column(k, rlist[k], format_strings=formats[k].split(','))) print print "Printing %i of %i reflections:" % (max_reflections, len(rlist)) for j in range(len(columns)): key = keys[j] width = max(len(key), columns[j].max_element_length()) print("%%%is" % width) % key, print for i in range(max_reflections): for j in range(len(columns)): print columns[j][i], print return
def run(args): import libtbx.load_env usage = """\ %s datablock.json reflections.pickle [options]""" % libtbx.env.dispatcher_name from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections from scitbx.array_family import flex from scitbx import matrix from libtbx.utils import Sorry parser = OptionParser(usage=usage, phil=master_phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False) params, options = parser.parse_args(show_diff_phil=True) datablocks = flatten_datablocks(params.input.datablock) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(datablocks) == 1: imageset = datablocks[0].extract_imagesets()[0] elif len(datablocks) > 1: raise Sorry("Only one DataBlock can be processed at a time") elif len(experiments.imagesets()) > 0: imageset = experiments.imagesets()[0] imageset.set_detector(experiments[0].detector) imageset.set_beam(experiments[0].beam) imageset.set_goniometer(experiments[0].goniometer) else: parser.print_help() return detector = imageset.get_detector() scan = imageset.get_scan() panel_origin_shifts = {0: (0, 0, 0)} try: hierarchy = detector.hierarchy() except AttributeError: hierarchy = None for i_panel in range(1, len(detector)): origin_shift = matrix.col(detector[0].get_origin()) \ - matrix.col(detector[i_panel].get_origin()) panel_origin_shifts[i_panel] = origin_shift observed_xyz = flex.vec3_double() predicted_xyz = flex.vec3_double() for reflection_list in reflections: if len(params.scan_range): sel = flex.bool(len(reflection_list), False) xyzcal_px = None xyzcal_px = None if 'xyzcal.px' in reflection_list: xyzcal_px = reflection_list['xyzcal.px'] if 'xyzobs.px.value' in reflection_list: xyzobs_px = reflection_list['xyzobs.px.value'] if xyzcal_px is not None and not xyzcal_px.norms().all_eq(0): centroids_frame = xyzcal_px.parts()[2] elif xyzobs_px is not None and not xyzobs_px.norms().all_eq(0): centroids_frame = xyzobs_px.parts()[2] else: raise Sorry("No pixel coordinates given in input reflections.") reflections_in_range = False for scan_range in params.scan_range: if scan_range is None: continue range_start, range_end = scan_range sel |= ((centroids_frame >= range_start) & (centroids_frame < range_end)) reflection_list = reflection_list.select(sel) if params.first_n_reflections is not None: centroid_positions = reflection_list.centroid_position() centroids_frame = centroid_positions.parts()[2] perm = flex.sort_permutation(centroids_frame) perm = perm[:min(reflection_list.size(), params.first_n_reflections )] reflection_list = reflection_list.select(perm) if params.crystal_id is not None: reflection_list = reflection_list.select( reflection_list['id'] == params.crystal_id) xyzcal_px = None xyzcal_px = None xyzobs_mm = None xyzcal_mm = None if 'xyzcal.px' in reflection_list: xyzcal_px = reflection_list['xyzcal.px'] if 'xyzobs.px.value' in reflection_list: xyzobs_px = reflection_list['xyzobs.px.value'] if 'xyzcal.mm' in reflection_list: xyzcal_mm = reflection_list['xyzcal.mm'] if 'xyzobs.mm.value' in reflection_list: xyzobs_mm = reflection_list['xyzobs.mm.value'] panel_ids = reflection_list['panel'] if xyzobs_mm is None and xyzobs_px is not None: xyzobs_mm = flex.vec3_double() for i_panel in range(len(detector)): xyzobs_px_panel = xyzobs_px.select(panel_ids == i_panel) from dials.algorithms.centroid import centroid_px_to_mm_panel xyzobs_mm_panel, _, _ = centroid_px_to_mm_panel( detector[i_panel], scan, xyzobs_px_panel, flex.vec3_double(xyzobs_px_panel.size()), flex.vec3_double(xyzobs_px_panel.size())) xyzobs_mm.extend(xyzobs_mm_panel) if xyzobs_mm is not None: observed_xyz.extend(xyzobs_mm) if xyzcal_mm is not None: predicted_xyz.extend(xyzcal_mm) obs_x, obs_y, _ = observed_xyz.parts() pred_x, pred_y, _ = predicted_xyz.parts() try: import matplotlib if not params.output.show_plot: # http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear matplotlib.use('Agg') # use a non-interactive backend from matplotlib import pyplot except ImportError: raise Sorry("matplotlib must be installed to generate a plot.") fig = pyplot.figure() fig.set_size_inches(params.output.size_inches) fig.set_dpi(params.output.dpi) pyplot.axes().set_aspect('equal') marker_size = params.output.marker_size if obs_x.size(): pyplot.scatter(obs_x, obs_y, marker='o', c='white', s=marker_size, alpha=1) if pred_x.size(): pyplot.scatter(pred_x, pred_y, marker='+', s=marker_size, c='blue') #assert len(detector) == 1 panel = detector[0] #if len(detector) > 1: xmin = max([ detector[i_panel].get_image_size_mm()[0] + panel_origin_shifts[i_panel][0] for i_panel in range(len(detector)) ]) xmax = max([ detector[i_panel].get_image_size_mm()[0] + panel_origin_shifts[i_panel][0] for i_panel in range(len(detector)) ]) ymax = max([ detector[i_panel].get_image_size_mm()[1] + panel_origin_shifts[i_panel][1] for i_panel in range(len(detector)) ]) ymax = max([ detector[i_panel].get_image_size_mm()[1] + panel_origin_shifts[i_panel][1] for i_panel in range(len(detector)) ]) try: beam_centre = hierarchy.get_beam_centre(imageset.get_beam().get_s0()) except Exception: beam_centre = detector[0].get_beam_centre(imageset.get_beam().get_s0()) pyplot.scatter([beam_centre[0]], [beam_centre[1]], marker='+', c='blue', s=100) pyplot.xlim(0, xmax) pyplot.ylim(0, ymax) pyplot.gca().invert_yaxis() pyplot.title('Centroid x,y-coordinates') pyplot.xlabel('x-coordinate (mm)') pyplot.ylabel('y-coordinate (mm)') if params.output.file_name is not None: pyplot.savefig(params.output.file_name, size_inches=params.output.size_inches, dpi=params.output.dpi, bbox_inches='tight') if params.output.show_plot: pyplot.show()
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections from dials.util import log import libtbx.load_env usage = "%s [options] datablock.json reflections.pickle" % ( libtbx.env.dispatcher_name) parser = OptionParser(usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args() datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0: parser.print_help() exit(0) # Configure the logging log.config(info='dials.rl_png.log') # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) reflections = reflections[0] if len(datablocks) == 0 and len(experiments) > 0: imagesets = experiments.imagesets() else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) f = ReciprocalLatticePng(settings=params) f.load_models(imagesets, reflections, None) imageset = imagesets[0] rotation_axis = matrix.col(imageset.get_goniometer().get_rotation_axis()) s0 = matrix.col(imageset.get_beam().get_s0()) e1 = rotation_axis.normalize() e2 = s0.normalize() e3 = e1.cross(e2).normalize() #print e1 #print e2 #print e3 f.viewer.plot('rl_rotation_axis.png', n=e1.elems) f.viewer.plot('rl_beam_vector', n=e2.elems) f.viewer.plot('rl_e3.png', n=e3.elems) n_solutions = params.basis_vector_search.n_solutions if len(experiments): for i, c in enumerate(experiments.crystals()): A = matrix.sqr(c.get_A()) astar = A[:3] bstar = A[3:6] cstar = A[6:9] direct_matrix = A.inverse() a = direct_matrix[:3] b = direct_matrix[3:6] c = direct_matrix[6:9] prefix = '' if len(experiments.crystals()) > 1: prefix = '%i_' % (i + 1) f.viewer.plot('rl_%sa.png' % prefix, n=a) f.viewer.plot('rl_%sb.png' % prefix, n=b) f.viewer.plot('rl_%sc.png' % prefix, n=c) elif n_solutions: from dials.command_line.discover_better_experimental_model \ import run_dps, dps_phil_scope hardcoded_phil = dps_phil_scope.extract() hardcoded_phil.d_min = params.d_min imageset = imagesets[0] from dials.algorithms.indexing.indexer import indexer_base if 'imageset_id' not in reflections: reflections['imageset_id'] = reflections['id'] spots_mm = indexer_base.map_spots_pixel_to_mm_rad( spots=reflections, detector=imageset.get_detector(), scan=imageset.get_scan()) indexer_base.map_centroids_to_reciprocal_space( spots_mm, detector=imageset.get_detector(), beam=imageset.get_beam(), goniometer=imageset.get_goniometer()) if params.d_min is not None: d_spacings = 1 / spots_mm['rlp'].norms() sel = d_spacings > params.d_min spots_mm = spots_mm.select(sel) # derive a max_cell from mm spots from dials.algorithms.indexing.indexer import find_max_cell max_cell = find_max_cell(spots_mm, max_cell_multiplier=1.3, step_size=45, nearest_neighbor_percentile=0.05).max_cell result = run_dps((imageset, spots_mm, max_cell, hardcoded_phil)) solutions = [matrix.col(v) for v in result['solutions']] for i in range(min(n_solutions, len(solutions))): v = solutions[i] #if i > 0: #for v1 in solutions[:i-1]: #angle = v.angle(v1, deg=True) #print angle f.viewer.plot('rl_solution_%s.png' % (i + 1), n=v.elems)
class Script(object): """ Encapsulate the script in a class. """ def __init__(self): """ Initialise the script. """ from dials.util.options import OptionParser usage = "usage: dials.create_profile_model [options] models.expt spots.refl" self.parser = OptionParser( usage=usage, epilog=help_message, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, ) def run(self): """ Run the script. """ from dials.algorithms.profile_model.factory import ProfileModelFactory from dials.util.command_line import Command from dials.array_family import flex from dials.util.options import flatten_reflections, flatten_experiments from dials.util import Sorry from dials.util import log log.config() # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(reflections) == 0 and len(experiments) == 0: self.parser.print_help() return if len(reflections) != 1: raise Sorry("exactly 1 reflection table must be specified") if len(experiments) == 0: raise Sorry("no experiments were specified") if ("background.mean" not in reflections[0]) and params.subtract_background: raise Sorry( "for subtract_background need background.mean in reflections") reflections, _ = self.process_reference(reflections[0], params) # Check pixels don't belong to neighbours self.filter_reference_pixels(reflections, experiments) # Predict the reflections logger.info("") logger.info("=" * 80) logger.info("") logger.info("Predicting reflections") logger.info("") predicted = flex.reflection_table.from_predictions_multi( experiments, dmin=params.prediction.d_min, dmax=params.prediction.d_max, margin=params.prediction.margin, force_static=params.prediction.force_static, padding=params.prediction.padding, ) # Match with predicted matched, reflections, unmatched = predicted.match_with_reference( reflections) assert len(matched) == len(predicted) assert matched.count(True) <= len(reflections) if matched.count(True) == 0: raise Sorry(""" Invalid input for reference reflections. Zero reference spots were matched to predictions """) elif len(unmatched) != 0: logger.info("") logger.info("*" * 80) logger.info( "Warning: %d reference spots were not matched to predictions" % (len(unmatched))) logger.info("*" * 80) logger.info("") # Create the profile model experiments = ProfileModelFactory.create(params, experiments, reflections) for model in experiments: sigma_b = model.profile.sigma_b(deg=True) sigma_m = model.profile.sigma_m(deg=True) if model.profile.is_scan_varying(): # scan varying mean_sigma_b = sum(sigma_b) / len(sigma_b) mean_sigma_m = sum(sigma_m) / len(sigma_m) logger.info("Sigma B: %f", mean_sigma_b) logger.info("Sigma M: %f", mean_sigma_m) else: logger.info("Sigma B: %f", sigma_b) logger.info("Sigma M: %f", sigma_m) # Write the parameters Command.start("Writing experiments to %s" % params.output) experiments.as_file(params.output) Command.end("Wrote experiments to %s" % params.output) def process_reference(self, reference, params): """ Load the reference spots. """ from time import time from dials.util import Sorry if reference is None: return None, None st = time() assert "miller_index" in reference assert "id" in reference logger.info("Processing reference reflections") logger.info(" read %d strong spots" % len(reference)) mask = reference.get_flags(reference.flags.indexed) rubbish = reference.select(~mask) if mask.count(False) > 0: reference.del_selected(~mask) logger.info(" removing %d unindexed reflections" % mask.count(False)) if len(reference) == 0: raise Sorry(""" Invalid input for reference reflections. Expected > %d indexed spots, got %d """ % (0, len(reference))) mask = reference.get_flags(reference.flags.centroid_outlier) if mask.count(True) > 0: rubbish.extend(reference.select(mask)) reference.del_selected(mask) logger.info( " removing %d reflections marked as centroid outliers" % mask.count(True)) mask = reference["miller_index"] == (0, 0, 0) if mask.count(True) > 0: rubbish.extend(reference.select(mask)) reference.del_selected(mask) logger.info(" removing %d reflections with hkl (0,0,0)" % mask.count(True)) mask = reference["id"] < 0 if mask.count(True) > 0: raise Sorry(""" Invalid input for reference reflections. %d reference spots have an invalid experiment id """ % mask.count(True)) logger.info(" using %d indexed reflections" % len(reference)) logger.info(" found %d junk reflections" % len(rubbish)) if "background.mean" in reference and params.subtract_background: logger.info( " subtracting background from %d reference reflections" % len(reference)) for spot in reference: spot["shoebox"].data -= spot["background.mean"] logger.info(" time taken: %g" % (time() - st)) return reference, rubbish def filter_reference_pixels(self, reference, experiments): """ Set any pixel closer to other reflections to background """ modified_count = 0 for experiment, indices in reference.iterate_experiments_and_indices( experiments): subset = reference.select(indices) modified = subset["shoebox"].mask_neighbouring( subset["miller_index"], experiment.beam, experiment.detector, experiment.goniometer, experiment.scan, experiment.crystal, ) modified_count += modified.count(True) reference.set_selected(indices, subset) logger.info(" masked neighbouring pixels in %d shoeboxes" % modified_count) return reference
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections import libtbx.load_env usage = "%s [options] datablock.json" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, check_format=True, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if (len(reflections) == 0 or len(experiments) == 0): parser.print_help() exit(0) reflections = reflections[0] assert len(experiments) == 1 experiment = experiments[0] from dials.command_line.check_strategy import filter_shadowed_reflections sel = filter_shadowed_reflections(experiments, reflections) print "%i/%i (%.2f%%) shadowed reflections" %( sel.count(True), sel.size(), 100*sel.count(True)/sel.size()) if params.negate: sel = ~sel shadowed = reflections.select(sel) shadowed.as_pickle(params.output.reflections) if params.output.filter_hkl is not None: from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame from scitbx import matrix detector = experiment.detector if len(detector) > 1: fast = detector[0].get_parent_fast_axis() slow = detector[0].get_parent_slow_axis() Rd = align_reference_frame(fast, (1,0,0), slow, (0,1,0)) origin = Rd * matrix.col(detector[0].get_parent_origin()) else: fast = detector[0].get_fast_axis() slow = detector[0].get_slow_axis() Rd = align_reference_frame(fast, (1,0,0), slow, (0,1,0)) origin = Rd * matrix.col(detector[0].get_origin()) with open(params.output.filter_hkl, 'wb') as f: for ref in shadowed: p = detector[ref['panel']] ox, oy = p.get_raw_image_offset() h, k, l = ref['miller_index'] x, y, z = ref['xyzcal.px'] dx, dy, dz = (2, 2, 2) print >> f, "%i %i %i %.1f %.1f %.1f %.1f %.1f %.1f" %( h, k, l, x+ox, y+oy, z, dx, dy, dz)
class Script(object): def __init__(self): """Initialise the script.""" from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = ("usage: %s [options] [param.phil] " "experiments1.expt experiments2.expt reflections1.refl " "reflections2.refl..." % libtbx.env.dispatcher_name) # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) def run(self): """Execute the script.""" params, options = self.parser.parse_args(show_diff_phil=True) self.run_with_preparsed(params, options) def run_with_preparsed(self, params, options): """Run combine_experiments, but allow passing in of parameters""" from dials.util.options import flatten_experiments # Try to load the models and data if len(params.input.experiments) == 0: print("No Experiments found in the input") self.parser.print_help() return if len(params.input.reflections) == 0: print("No reflection data found in the input") self.parser.print_help() return try: assert len(params.input.reflections) == len( params.input.experiments) except AssertionError: raise Sorry( "The number of input reflections files does not match the " "number of input experiments") flat_exps = flatten_experiments(params.input.experiments) ref_beam = params.reference_from_experiment.beam ref_goniometer = params.reference_from_experiment.goniometer ref_scan = params.reference_from_experiment.scan ref_crystal = params.reference_from_experiment.crystal ref_detector = params.reference_from_experiment.detector if ref_beam is not None: try: ref_beam = flat_exps[ref_beam].beam except IndexError: raise Sorry("{} is not a valid experiment ID".format(ref_beam)) if ref_goniometer is not None: try: ref_goniometer = flat_exps[ref_goniometer].goniometer except IndexError: raise Sorry( "{} is not a valid experiment ID".format(ref_goniometer)) if ref_scan is not None: try: ref_scan = flat_exps[ref_scan].scan except IndexError: raise Sorry("{} is not a valid experiment ID".format(ref_scan)) if ref_crystal is not None: try: ref_crystal = flat_exps[ref_crystal].crystal except IndexError: raise Sorry( "{} is not a valid experiment ID".format(ref_crystal)) if ref_detector is not None: assert not params.reference_from_experiment.average_detector try: ref_detector = flat_exps[ref_detector].detector except IndexError: raise Sorry( "{} is not a valid experiment ID".format(ref_detector)) elif params.reference_from_experiment.average_detector: # Average all of the detectors together from scitbx.matrix import col def average_detectors(target, panelgroups, depth): # Recursive function to do the averaging if (params.reference_from_experiment.average_hierarchy_level is None or depth == params.reference_from_experiment. average_hierarchy_level): n = len(panelgroups) sum_fast = col((0.0, 0.0, 0.0)) sum_slow = col((0.0, 0.0, 0.0)) sum_ori = col((0.0, 0.0, 0.0)) # Average the d matrix vectors for pg in panelgroups: sum_fast += col(pg.get_local_fast_axis()) sum_slow += col(pg.get_local_slow_axis()) sum_ori += col(pg.get_local_origin()) sum_fast /= n sum_slow /= n sum_ori /= n # Re-orthagonalize the slow and the fast vectors by rotating around the cross product c = sum_fast.cross(sum_slow) a = sum_fast.angle(sum_slow, deg=True) / 2 sum_fast = sum_fast.rotate(c, a - 45, deg=True) sum_slow = sum_slow.rotate(c, -(a - 45), deg=True) target.set_local_frame(sum_fast, sum_slow, sum_ori) if target.is_group(): # Recurse for i, target_pg in enumerate(target): average_detectors(target_pg, [pg[i] for pg in panelgroups], depth + 1) ref_detector = flat_exps[0].detector average_detectors(ref_detector.hierarchy(), [e.detector.hierarchy() for e in flat_exps], 0) combine = CombineWithReference( beam=ref_beam, goniometer=ref_goniometer, scan=ref_scan, crystal=ref_crystal, detector=ref_detector, params=params, ) # set up global experiments and reflections lists from dials.array_family import flex reflections = flex.reflection_table() global_id = 0 skipped_expts = 0 from dxtbx.model.experiment_list import ExperimentList experiments = ExperimentList() # loop through the input, building up the global lists nrefs_per_exp = [] for ref_wrapper, exp_wrapper in zip(params.input.reflections, params.input.experiments): refs = ref_wrapper.data exps = exp_wrapper.data for i, exp in enumerate(exps): sel = refs["id"] == i sub_ref = refs.select(sel) n_sub_ref = len(sub_ref) if (params.output.min_reflections_per_experiment is not None and n_sub_ref < params.output.min_reflections_per_experiment): skipped_expts += 1 continue nrefs_per_exp.append(n_sub_ref) sub_ref["id"] = flex.int(len(sub_ref), global_id) if params.output.delete_shoeboxes and "shoebox" in sub_ref: del sub_ref["shoebox"] reflections.extend(sub_ref) try: experiments.append(combine(exp)) except ComparisonError as e: # When we failed tolerance checks, give a useful error message (path, index) = find_experiment_in(exp, params.input.experiments) raise Sorry( "Model didn't match reference within required tolerance for experiment {} in {}:" "\n{}\nAdjust tolerances or set compare_models=False to ignore differences." .format(index, path, str(e))) global_id += 1 if (params.output.min_reflections_per_experiment is not None and skipped_expts > 0): print("Removed {0} experiments with fewer than {1} reflections". format(skipped_expts, params.output.min_reflections_per_experiment)) # print number of reflections per experiment from libtbx.table_utils import simple_table header = ["Experiment", "Number of reflections"] rows = [(str(i), str(n)) for (i, n) in enumerate(nrefs_per_exp)] st = simple_table(rows, header) print(st.format()) # save a random subset if requested if (params.output.n_subset is not None and len(experiments) > params.output.n_subset): subset_exp = ExperimentList() subset_refls = flex.reflection_table() if params.output.n_subset_method == "random": n_picked = 0 indices = list(range(len(experiments))) while n_picked < params.output.n_subset: idx = indices.pop(random.randint(0, len(indices) - 1)) subset_exp.append(experiments[idx]) refls = reflections.select(reflections["id"] == idx) refls["id"] = flex.int(len(refls), n_picked) subset_refls.extend(refls) n_picked += 1 print( "Selecting a random subset of {0} experiments out of {1} total." .format(params.output.n_subset, len(experiments))) elif params.output.n_subset_method == "n_refl": if params.output.n_refl_panel_list is None: refls_subset = reflections else: sel = flex.bool(len(reflections), False) for p in params.output.n_refl_panel_list: sel |= reflections["panel"] == p refls_subset = reflections.select(sel) refl_counts = flex.int() for expt_id in range(len(experiments)): refl_counts.append( len(refls_subset.select( refls_subset["id"] == expt_id))) sort_order = flex.sort_permutation(refl_counts, reverse=True) for expt_id, idx in enumerate( sort_order[:params.output.n_subset]): subset_exp.append(experiments[idx]) refls = reflections.select(reflections["id"] == idx) refls["id"] = flex.int(len(refls), expt_id) subset_refls.extend(refls) print( "Selecting a subset of {0} experiments with highest number of reflections out of {1} total." .format(params.output.n_subset, len(experiments))) elif params.output.n_subset_method == "significance_filter": from dials.algorithms.integration.stills_significance_filter import ( SignificanceFilter, ) params.output.significance_filter.enable = True sig_filter = SignificanceFilter(params.output) refls_subset = sig_filter(experiments, reflections) refl_counts = flex.int() for expt_id in range(len(experiments)): refl_counts.append( len(refls_subset.select( refls_subset["id"] == expt_id))) sort_order = flex.sort_permutation(refl_counts, reverse=True) for expt_id, idx in enumerate( sort_order[:params.output.n_subset]): subset_exp.append(experiments[idx]) refls = reflections.select(reflections["id"] == idx) refls["id"] = flex.int(len(refls), expt_id) subset_refls.extend(refls) experiments = subset_exp reflections = subset_refls def save_in_batches(experiments, reflections, exp_name, refl_name, batch_size=1000): from dxtbx.command_line.image_average import splitit for i, indices in enumerate( splitit(list(range(len(experiments))), (len(experiments) // batch_size) + 1)): batch_expts = ExperimentList() batch_refls = flex.reflection_table() for sub_id, sub_idx in enumerate(indices): batch_expts.append(experiments[sub_idx]) sub_refls = reflections.select( reflections["id"] == sub_idx) sub_refls["id"] = flex.int(len(sub_refls), sub_id) batch_refls.extend(sub_refls) exp_filename = os.path.splitext(exp_name)[0] + "_%03d.expt" % i ref_filename = os.path.splitext( refl_name)[0] + "_%03d.refl" % i self._save_output(batch_expts, batch_refls, exp_filename, ref_filename) def combine_in_clusters(experiments_l, reflections_l, exp_name, refl_name, end_count): result = [] for cluster, experiment in enumerate(experiments_l): cluster_expts = ExperimentList() cluster_refls = flex.reflection_table() for i, expts in enumerate(experiment): refls = reflections_l[cluster][i] refls["id"] = flex.int(len(refls), i) cluster_expts.append(expts) cluster_refls.extend(refls) exp_filename = os.path.splitext(exp_name)[0] + ( "_cluster%d.expt" % (end_count - cluster)) ref_filename = os.path.splitext(refl_name)[0] + ( "_cluster%d.refl" % (end_count - cluster)) result.append( (cluster_expts, cluster_refls, exp_filename, ref_filename)) return result # cluster the resulting experiments if requested if params.clustering.use: clustered = Cluster( experiments, reflections, dendrogram=params.clustering.dendrogram, threshold=params.clustering.threshold, n_max=params.clustering.max_crystals, ) n_clusters = len(clustered.clustered_frames) def not_too_many(keeps): if params.clustering.max_clusters is not None: return len(keeps) < params.clustering.max_clusters return True keep_frames = [] sorted_keys = sorted(clustered.clustered_frames.keys()) while len(clustered.clustered_frames) > 0 and not_too_many( keep_frames): keep_frames.append( clustered.clustered_frames.pop(sorted_keys.pop(-1))) if params.clustering.exclude_single_crystal_clusters: keep_frames = [k for k in keep_frames if len(k) > 1] clustered_experiments = [[f.experiment for f in frame_cluster] for frame_cluster in keep_frames] clustered_reflections = [[f.reflections for f in frame_cluster] for frame_cluster in keep_frames] list_of_combined = combine_in_clusters( clustered_experiments, clustered_reflections, params.output.experiments_filename, params.output.reflections_filename, n_clusters, ) for saveable_tuple in list_of_combined: if params.output.max_batch_size is None: self._save_output(*saveable_tuple) else: save_in_batches(*saveable_tuple, batch_size=params.output.max_batch_size) else: if params.output.max_batch_size is None: self._save_output( experiments, reflections, params.output.experiments_filename, params.output.reflections_filename, ) else: save_in_batches( experiments, reflections, params.output.experiments_filename, params.output.reflections_filename, batch_size=params.output.max_batch_size, ) return def _save_output(self, experiments, reflections, exp_name, refl_name): # save output print("Saving combined experiments to {}".format(exp_name)) experiments.as_file(exp_name) print("Saving combined reflections to {}".format(refl_name)) reflections.as_file(refl_name)
class Script(object): """A class for running the script.""" def __init__(self): """Initialise the script.""" from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = ( "usage: %s [options] experiment_one.expt experiment_two.expt" % libtbx.env.dispatcher_name) # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, epilog=help_message, check_format=False, read_experiments=True, ) def run(self): """Execute the script.""" from dials.util.options import flatten_experiments # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) # Check the number of experiments is at least 2 experiments = flatten_experiments(params.input.experiments) if len(experiments) < 2: self.parser.print_help() return detectors = [experiment.detector[0] for experiment in experiments] from itertools import combinations for pair in combinations(detectors, 2): determine_axis(pair, params) from scitbx import matrix from scitbx.math import r3_rotation_axis_and_angle_from_matrix crystals = [experiment.crystal for experiment in experiments] goniometers = [experiment.goniometer for experiment in experiments] FUs = [] for c, g in zip(crystals, goniometers): u = matrix.sqr(c.get_U()) f = matrix.sqr(g.get_fixed_rotation()) FUs.append(f * u) for pair in combinations(FUs, 2): R = pair[1] * pair[0].inverse() rot = r3_rotation_axis_and_angle_from_matrix(R) angle = rot.angle(deg=True) axis = matrix.col(rot.axis) if abs(angle) < 10: continue print("Axis: %8.5f %8.5f %8.5f" % axis.elems, "angle: %7.4f" % angle)
def run(args=None): usage = "dials.align_crystal [options] models.expt" parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(args, show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: parser.print_help() exit(0) expt = experiments[0] if params.space_group is not None: expt.crystal.set_space_group(params.space_group.group()) if len(params.align.crystal.vector): frame = None assert len(params.align.crystal.vector) % 2 == 0 vectors = [] name_to_vectors = { "a": (a, "direct"), "b": (b, "direct"), "c": (c, "direct"), "a*": (a_star, "reciprocal"), "b*": (b_star, "reciprocal"), "c*": (c_star, "reciprocal"), } for v in params.align.crystal.vector: v = v.strip() if v in name_to_vectors: v, frame_ = name_to_vectors[v] assert frame is None or frame == frame_ frame = frame_ else: v = v.replace(",", " ").strip().split() assert len(v) == 3 v = matrix.col([float(v_) for v_ in v]) if frame is None: frame = params.align.crystal.frame vectors.append(v) vectors = [ (vectors[2 * i], vectors[2 * i + 1]) for i in range(len(vectors) // 2) ] elif params.align.crystal.frame == "direct": frame = params.align.crystal.frame vectors = ((a, b), (a, c), (b, a), (b, c), (c, a), (c, b)) else: frame = "reciprocal" vectors = ( (a_star, b_star), # a*, b* (a_star, c_star), # a*, c* (b_star, a_star), # b*, a* (b_star, c_star), # b*, c* (c_star, a_star), # c*, a* (c_star, b_star), # c*, b* ) try: result = align_crystal(expt, vectors, frame=frame, mode=params.align.mode) print(result) except ValueError as e: sys.exit(e) if params.output.json is not None: result.as_json(filename=params.output.json)
def run(args=None): usage = "dials.spot_counts_per_image [options] imported.expt strong.refl" parser = OptionParser( usage=usage, read_reflections=True, read_experiments=True, phil=phil_scope, check_format=False, epilog=help_message, ) params, options = parser.parse_args(args, show_diff_phil=False) reflections, experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments) if not reflections and not experiments: parser.print_help() return # FIXME may want to change this to allow many to be passed i.e. # from parallel runs if len(reflections) != 1: sys.exit("Only one reflection list may be passed") reflections = reflections[0] reflections.centroid_px_to_mm(experiments) reflections.map_centroids_to_reciprocal_space(experiments) if params.id is not None: reflections = reflections.select(reflections["id"] == params.id) all_stats = [] for i, expt in enumerate(experiments): refl = reflections.select(reflections["id"] == i) stats = per_image_analysis.stats_per_image( expt, refl, resolution_analysis=params.resolution_analysis) all_stats.append(stats) # transpose stats summary_table = {} for s in all_stats: for k, value in s._asdict().items(): summary_table.setdefault(k, []) summary_table[k].extend(value) stats = per_image_analysis.StatsMultiImage(**summary_table) print(stats) overall_stats = per_image_analysis.stats_for_reflection_table( reflections, resolution_analysis=params.resolution_analysis) rows = [ ("Overall statistics", ""), ("#spots", "%i" % overall_stats.n_spots_total), ("#spots_no_ice", "%i" % overall_stats.n_spots_no_ice), ("d_min", f"{overall_stats.estimated_d_min:.2f}"), ( "d_min (distl method 1)", "%.2f (%.2f)" % (overall_stats.d_min_distl_method_1, overall_stats.noisiness_method_1), ), ( "d_min (distl method 2)", "%.2f (%.2f)" % (overall_stats.d_min_distl_method_2, overall_stats.noisiness_method_2), ), ] print(tabulate(rows, headers="firstrow")) if params.json: if params.split_json: for k, v in stats._asdict().items(): start, end = params.json.split(".") with open(f"{start}_{k}.{end}", "w") as fp: json.dump(v, fp) if params.joint_json: with open(params.json, "w") as fp: json.dump(stats._asdict(), fp) if params.plot: import matplotlib matplotlib.use("Agg") per_image_analysis.plot_stats(stats, filename=params.plot)
class Script(object): def __init__(self): """Initialise the script.""" # The script usage usage = ( "usage: dials.rs_mapper map_file=output.ccp4 [max_resolution=6] [grid_size=192] " "[reverse_phi=False] [param.phil] " "{image1.file [image2.file ...]} | imported.expt") # Initialise the base class self.parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message, read_experiments=True) def run(self): # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) if not params.rs_mapper.map_file: raise RuntimeError("Please specify output map file (map_file=)") else: self.map_file = params.rs_mapper.map_file # Ensure we have either a data block or an experiment list self.experiments = flatten_experiments(params.input.experiments) if len(self.experiments) != 1: self.parser.print_help() print("Please pass either an experiment list\n") return self.reverse_phi = params.rs_mapper.reverse_phi self.grid_size = params.rs_mapper.grid_size self.max_resolution = params.rs_mapper.max_resolution self.ignore_mask = params.rs_mapper.ignore_mask self.grid = flex.double( flex.grid(self.grid_size, self.grid_size, self.grid_size), 0) self.counts = flex.int( flex.grid(self.grid_size, self.grid_size, self.grid_size), 0) for experiment in self.experiments: self.process_imageset(experiment.imageset) recviewer.normalize_voxels(self.grid, self.counts) # Let's use 1/(100A) as the unit so that the absolute numbers in the # "cell dimensions" field of the ccp4 map are typical for normal # MX maps. The values in 1/A would give the "cell dimensions" around # or below 1 and some MX programs would not handle it well. box_size = 100 * 2.0 / self.max_resolution uc = uctbx.unit_cell((box_size, box_size, box_size, 90, 90, 90)) ccp4_map.write_ccp4_map( self.map_file, uc, sgtbx.space_group("P1"), (0, 0, 0), self.grid.all(), self.grid, flex.std_string(["cctbx.miller.fft_map"]), ) def process_imageset(self, imageset): rec_range = 1 / self.max_resolution if len(imageset.get_detector()) != 1: raise Sorry("This program does not support multi-panel detectors.") panel = imageset.get_detector()[0] beam = imageset.get_beam() s0 = beam.get_s0() pixel_size = panel.get_pixel_size() xlim, ylim = imageset.get_raw_data(0)[0].all() if pixel_size[0] != pixel_size[1]: raise Sorry("This program does not support non-square pixels.") # cache transformation xy = recviewer.get_target_pixels(panel, s0, xlim, ylim, self.max_resolution) s1 = panel.get_lab_coord(xy * pixel_size[0]) s1 = s1 / s1.norms() * (1 / beam.get_wavelength()) S = s1 - s0 for i in range(len(imageset)): axis = imageset.get_goniometer().get_rotation_axis() osc_range = imageset.get_scan(i).get_oscillation_range() print("Oscillation range: %.2f - %.2f" % (osc_range[0], osc_range[1])) angle = (osc_range[0] + osc_range[1]) / 2 / 180 * math.pi if not self.reverse_phi: # the pixel is in S AFTER rotation. Thus we have to rotate BACK. angle *= -1 rotated_S = S.rotate_around_origin(axis, angle) data = imageset.get_raw_data(i)[0] if not self.ignore_mask: mask = imageset.get_mask(i)[0] data.set_selected(~mask, 0) recviewer.fill_voxels(data, self.grid, self.counts, rotated_S, xy, rec_range)
def run(args): from dials.util import log from dials.util.options import OptionParser, reflections_and_experiments_from_files usage = "dials.detect_blanks [options] models.expt observations.refl" parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(args) reflections, experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments) if len(experiments) == 0 or len(reflections) == 0: parser.print_help() exit(0) # Configure the logging log.config(logfile="dials.detect_blanks.log") # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil != "": logger.info("The following parameters have been modified:\n") logger.info(diff_phil) reflections = reflections[0] imagesets = experiments.imagesets() if any(experiment.is_still() for experiment in experiments): sys.exit("dials.detect_blanks can only be used with rotation data") assert len(imagesets) == 1 imageset = imagesets[0] scan = imageset.get_scan() integrated_sel = reflections.get_flags(reflections.flags.integrated) indexed_sel = reflections.get_flags(reflections.flags.indexed) centroid_outlier_sel = reflections.get_flags( reflections.flags.centroid_outlier) strong_sel = reflections.get_flags(reflections.flags.strong) indexed_sel &= ~centroid_outlier_sel logger.info(f"Analysis of {strong_sel.count(True)} strong reflections:") strong_results = detect_blanks.blank_counts_analysis( reflections.select(strong_sel), scan, phi_step=params.phi_step, fractional_loss=params.counts_fractional_loss, ) for blank_start, blank_end in strong_results["blank_regions"]: logger.info( f"Potential blank images: {blank_start + 1} -> {blank_end}") indexed_results = None if indexed_sel.count(True) > 0: logger.info( f"Analysis of {indexed_sel.count(True)} indexed reflections:") indexed_results = detect_blanks.blank_counts_analysis( reflections.select(indexed_sel), scan, phi_step=params.phi_step, fractional_loss=params.counts_fractional_loss, ) for blank_start, blank_end in indexed_results["blank_regions"]: logger.info( f"Potential blank images: {blank_start + 1} -> {blank_end}") integrated_results = None if integrated_sel.count(True) > 0: logger.info( f"Analysis of {integrated_sel.count(True)} integrated reflections:" ) integrated_results = detect_blanks.blank_integrated_analysis( reflections.select(integrated_sel), scan, phi_step=params.phi_step, fractional_loss=params.misigma_fractional_loss, ) for blank_start, blank_end in integrated_results["blank_regions"]: logger.info( f"Potential blank images: {blank_start + 1} -> {blank_end}") d = { "strong": strong_results, "indexed": indexed_results, "integrated": integrated_results, } if params.output.json is not None: with open(params.output.json, "w") as fh: json.dump(d, fh) if params.output.plot: from matplotlib import pyplot plots = [(strong_results, "-")] if indexed_results: plots.append((indexed_results, "--")) if integrated_results: plots.append((integrated_results, ":")) for results, linestyle in plots: xs = results["data"][0]["x"] ys = results["data"][0]["y"] xmax = max(xs) ymax = max(ys) xs = [x / xmax for x in xs] ys = [y / ymax for y in ys] blanks = results["data"][0]["blank"] pyplot.plot(xs, ys, color="blue", linestyle=linestyle) pyplot.plot( *zip(*[(x, y) for x, y, blank in zip(xs, ys, blanks) if blank]), color="red", linestyle=linestyle, ) pyplot.ylim(0) pyplot.show() pyplot.clf()
class Script(object): """A class for running the script.""" def __init__(self): """Initialise the script.""" # The script usage usage = ( "usage: dials.two_theta_refine [options] [param.phil] " "models.expt observations.refl" ) # Create the parser self.parser = OptionParser( usage=usage, phil=working_phil, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) @staticmethod def check_input(reflections): """Check the input is suitable for refinement. So far just check keys in the reflection table. Maybe later check experiments have overlapping models etc.""" msg = ( "The supplied reflection table does not have the required data " + "column: {0}" ) for key in ["xyzobs.mm.value", "xyzobs.mm.variance"]: if key not in reflections: msg = msg.format(key) sys.exit(msg) # FIXME add other things to be checked here return @staticmethod def combine_crystals(experiments): """Replace all crystals in the experiments list with the first crystal""" new_experiments = ExperimentList() ref_crystal = experiments[0].crystal for exp in experiments: new_experiments.append( Experiment( beam=exp.beam, detector=exp.detector, scan=exp.scan, goniometer=exp.goniometer, crystal=ref_crystal, imageset=exp.imageset, identifier=exp.identifier, ) ) return new_experiments @staticmethod def filter_integrated_centroids(reflections): """Filter reflections to include only those with the integrated and the strong flag set, but only if there are apparently some integrated reflections""" orig_len = len(reflections) mask = reflections.get_flags(reflections.flags.integrated) if mask.count(True) == 0: return reflections reflections = reflections.select(mask) mask = reflections.get_flags(reflections.flags.strong) reflections = reflections.select(mask) logger.info( "{0} out of {1} reflections remain after filtering to keep only strong" " and integrated centroids".format(len(reflections), orig_len) ) return reflections @staticmethod def convert_to_P1(reflections, experiments): """Convert the input crystals to P 1 and reindex the reflections""" for iexp, exp in enumerate(experiments): sel = reflections["id"] == iexp xl = exp.crystal sg = xl.get_space_group() op = sg.info().change_of_basis_op_to_primitive_setting() exp.crystal = xl.change_basis(op) exp.crystal.set_space_group(sgtbx.space_group("P 1")) hkl_reindexed = op.apply(reflections["miller_index"].select(sel)) reflections["miller_index"].set_selected(sel, hkl_reindexed) return reflections, experiments @staticmethod def create_refiner(params, reflections, experiments): # Only parameterise the crystal unit cell det_params = None beam_params = None xlo_params = None xluc_params = [] for crystal in experiments.crystals(): exp_ids = experiments.indices(crystal) xluc_params.append( CrystalUnitCellParameterisation(crystal, experiment_ids=exp_ids) ) # Two theta prediction equation parameterisation pred_param = TwoThetaPredictionParameterisation( experiments, det_params, beam_params, xlo_params, xluc_params ) param_reporter = ParameterReporter( det_params, beam_params, xlo_params, xluc_params ) # ReflectionManager, currently without outlier rejection # Note: If not all reflections are used, then the filtering must be # communicated to generate_cif/mmcif() to be included in the CIF file! refman = TwoThetaReflectionManager( reflections, experiments, outlier_detector=None ) # Reflection predictor ref_predictor = TwoThetaExperimentsPredictor(experiments) # Two theta target target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param) # Switch on correlation matrix tracking if a correlation plot is requested journal = None if params.output.correlation_plot.filename is not None: journal = refinery_phil_scope.extract().refinery.journal journal.track_parameter_correlation = True # Minimisation engine - hardcoded to LevMar for now. refinery = Refinery( target=target, prediction_parameterisation=pred_param, log=None, tracking=journal, max_iterations=20, ) # Refiner refiner = Refiner( experiments=experiments, pred_param=pred_param, param_reporter=param_reporter, refman=refman, target=target, refinery=refinery, ) return refiner @staticmethod def cell_param_table(crystal): """Construct a table of cell parameters and their ESDs""" cell = crystal.get_unit_cell().parameters() esd = crystal.get_cell_parameter_sd() vol = crystal.get_unit_cell().volume() vol_esd = crystal.get_cell_volume_sd() header = ["Parameter", "Value", "Estimated sd"] rows = [] names = ["a", "b", "c", "alpha", "beta", "gamma"] for n, p, e in zip(names, cell, esd): rows.append([n, "%9.5f" % p, "%9.5f" % e]) rows.append(["\nvolume", "\n%9.5f" % vol, "\n%9.5f" % vol_esd]) return tabulate(rows, header) @staticmethod def generate_p4p(crystal, beam, filename): logger.info("Saving P4P info to %s", filename) cell = crystal.get_unit_cell().parameters() esd = crystal.get_cell_parameter_sd() vol = crystal.get_unit_cell().volume() vol_esd = crystal.get_cell_volume_sd() open(filename, "w").write( "\n".join( [ "TITLE Auto-generated .p4p file from dials.two_theta_refine", "CELL %.4f %.4f %.4f %.4f %.4f %.4f %.4f" % tuple(cell + (vol,)), "CELLSD %.4f %.4f %.4f %.4f %.4f %.4f %.4f" % tuple(esd + (vol_esd,)), "SOURCE SYNCH %.6f" % beam.get_wavelength(), "", ] ) ) return @staticmethod def generate_cif(crystal, refiner, filename): logger.info("Saving CIF information to %s", filename) block = iotbx.cif.model.block() block["_audit_creation_method"] = dials_version() block["_audit_creation_date"] = datetime.date.today().isoformat() # block["_publ_section_references"] = '' # once there is a reference... for cell, esd, cifname in zip( crystal.get_unit_cell().parameters(), crystal.get_cell_parameter_sd(), [ "length_a", "length_b", "length_c", "angle_alpha", "angle_beta", "angle_gamma", ], ): block["_cell_%s" % cifname] = format_float_with_standard_uncertainty( cell, esd ) block["_cell_volume"] = format_float_with_standard_uncertainty( crystal.get_unit_cell().volume(), crystal.get_cell_volume_sd() ) used_reflections = refiner.get_matches() block["_cell_measurement_reflns_used"] = len(used_reflections) block["_cell_measurement_theta_min"] = ( flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) block["_cell_measurement_theta_max"] = ( flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) block["_diffrn_reflns_number"] = len(used_reflections) miller_span = miller.index_span(used_reflections["miller_index"]) min_h, min_k, min_l = miller_span.min() max_h, max_k, max_l = miller_span.max() block["_diffrn_reflns_limit_h_min"] = min_h block["_diffrn_reflns_limit_h_max"] = max_h block["_diffrn_reflns_limit_k_min"] = min_k block["_diffrn_reflns_limit_k_max"] = max_k block["_diffrn_reflns_limit_l_min"] = min_l block["_diffrn_reflns_limit_l_max"] = max_l block["_diffrn_reflns_theta_min"] = ( flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) block["_diffrn_reflns_theta_max"] = ( flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) cif = iotbx.cif.model.cif() cif["two_theta_refine"] = block with open(filename, "w") as fh: cif.show(out=fh) @staticmethod def generate_mmcif(crystal, refiner, filename): logger.info("Saving mmCIF information to %s", filename) block = iotbx.cif.model.block() block["_audit.creation_method"] = dials_version() block["_audit.creation_date"] = datetime.date.today().isoformat() # block["_publ.section_references"] = '' # once there is a reference... for cell, esd, cifname in zip( crystal.get_unit_cell().parameters(), crystal.get_cell_parameter_sd(), [ "length_a", "length_b", "length_c", "angle_alpha", "angle_beta", "angle_gamma", ], ): block["_cell.%s" % cifname] = "%.8f" % cell block["_cell.%s_esd" % cifname] = "%.8f" % esd block["_cell.volume"] = "%f" % crystal.get_unit_cell().volume() block["_cell.volume_esd"] = "%f" % crystal.get_cell_volume_sd() used_reflections = refiner.get_matches() block["_cell_measurement.reflns_used"] = len(used_reflections) block["_cell_measurement.theta_min"] = ( flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) block["_cell_measurement.theta_max"] = ( flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) block["_diffrn_reflns.number"] = len(used_reflections) miller_span = miller.index_span(used_reflections["miller_index"]) min_h, min_k, min_l = miller_span.min() max_h, max_k, max_l = miller_span.max() block["_diffrn_reflns.limit_h_min"] = min_h block["_diffrn_reflns.limit_h_max"] = max_h block["_diffrn_reflns.limit_k_min"] = min_k block["_diffrn_reflns.limit_k_max"] = max_k block["_diffrn_reflns.limit_l_min"] = min_l block["_diffrn_reflns.limit_l_max"] = max_l block["_diffrn_reflns.theta_min"] = ( flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) block["_diffrn_reflns.theta_max"] = ( flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2 ) cif = iotbx.cif.model.cif() cif["two_theta_refine"] = block with open(filename, "w") as fh: cif.show(out=fh) def run(self): """Execute the script.""" # Parse the command line params, _ = self.parser.parse_args(show_diff_phil=False) # set up global reflections list reflections = flex.reflection_table() # loop through the input, building up the global lists reflections_list, input_experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments ) experiments = copy.deepcopy(input_experiments) reflections_list = parse_multiple_datasets(reflections_list) for refs in reflections_list: reflections.extend(refs) # Try to load the models and data nexp = len(experiments) if nexp == 0: print("No Experiments found in the input") self.parser.print_help() return if not reflections: print("No reflection data found in the input") self.parser.print_help() return self.check_input(reflections) # Configure the logging log.config(logfile=params.output.log) logger.info(dials_version()) # Log the diff phil diff_phil = self.parser.diff_phil.as_str() if diff_phil != "": logger.info("The following parameters have been modified:\n") logger.info(diff_phil) # Convert to P 1? if params.refinement.triclinic: reflections, experiments = self.convert_to_P1(reflections, experiments) # Combine crystals? if params.refinement.combine_crystal_models and len(experiments) > 1: logger.info("Combining {0} crystal models".format(len(experiments))) experiments = self.combine_crystals(experiments) # Filter integrated centroids? if params.refinement.filter_integrated_centroids: reflections = self.filter_integrated_centroids(reflections) # Filter data if scaled to remove outliers if "inverse_scale_factor" in reflections: try: reflections = filter_reflection_table(reflections, ["scale"]) except ValueError as e: logger.warn(e) logger.info( "Filtering on scaled data failed, proceeding with integrated data." ) # Get the refiner logger.info("Configuring refiner") refiner = self.create_refiner(params, reflections, experiments) # Refine the geometry if nexp == 1: logger.info("Performing refinement of a single Experiment...") else: logger.info("Performing refinement of {} Experiments...".format(nexp)) refiner.run() # get the refined experiments experiments = copy.deepcopy(input_experiments) for expt, refined_expt in zip(experiments, refiner.get_experiments()): expt.crystal.set_recalculated_unit_cell( refined_expt.crystal.get_unit_cell() ) expt.crystal.set_recalculated_cell_parameter_sd( refined_expt.crystal.get_cell_parameter_sd() ) expt.crystal.set_recalculated_cell_volume_sd( refined_expt.crystal.get_cell_volume_sd() ) crystals = refiner.get_experiments().crystals() if len(crystals) == 1: # output the refined model for information logger.info("") logger.info("Final refined crystal model:") logger.info(crystals[0]) logger.info(self.cell_param_table(crystals[0])) # Save the refined experiments to file output_experiments_filename = params.output.experiments logger.info( "Saving refined experiments to {}".format(output_experiments_filename) ) experiments.as_file(output_experiments_filename) # Create correlation plots if params.output.correlation_plot.filename is not None: create_correlation_plots(refiner, params.output) if params.output.cif is not None: self.generate_cif(crystals[0], refiner, filename=params.output.cif) if params.output.p4p is not None: self.generate_p4p( crystals[0], experiments[0].beam, filename=params.output.p4p ) if params.output.mmcif is not None: self.generate_mmcif(crystals[0], refiner, filename=params.output.mmcif)
class Script(object): """A class for running the script.""" def __init__(self): """Initialise the script.""" # The script usage usage = "usage: dials.complete_full_sphere [options] " # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, epilog=help_message, check_format=True, read_experiments=True, ) def run(self, args=None): params, options = self.parser.parse_args(args, show_diff_phil=True) log.config(logfile="dials.complete_full_sphere.log") model_shadow = params.shadow experiments = flatten_experiments(params.input.experiments) if len(experiments) != 1: self.parser.print_help() return expt = experiments[0] axes = expt.goniometer.get_axes() if len(axes) != 3: sys.exit("This will only work with 3-axis goniometers") if not expt.imageset.reader().get_format(): sys.exit("This will only work with images available") if not expt.imageset.reader().get_format( ).get_goniometer_shadow_masker(): model_shadow = False beam = expt.beam det = expt.detector if params.resolution: resolution = params.resolution else: resolution = det.get_max_inscribed_resolution(expt.beam.get_s0()) # at this point, predict all of the reflections in the scan possible (i.e. # extend scan to 360 degrees) - this points back to expt self.make_scan_360(expt.scan) # now get a full set of all unique miller indices all_indices = miller.build_set( crystal_symmetry=crystal.symmetry( space_group=expt.crystal.get_space_group(), unit_cell=expt.crystal.get_unit_cell(), ), anomalous_flag=True, d_min=resolution, ) if model_shadow: obs, shadow = self.predict_to_miller_set_with_shadow( expt, resolution) else: obs = self.predict_to_miller_set(expt, resolution) logger.info("Fraction of unique observations at datum: %.1f%%" % (100.0 * len(obs.indices()) / len(all_indices.indices()))) missing = all_indices.lone_set(other=obs) logger.info("%d unique reflections in blind region" % len(missing.indices())) e1 = matrix.col(axes[0]) e2 = matrix.col(axes[1]) e3 = matrix.col(axes[2]) s0n = matrix.col(beam.get_s0()).normalize() # rotate blind region about beam by +/- two theta two_theta = 2.0 * math.asin(0.5 * beam.get_wavelength() / resolution) R_ptt = s0n.axis_and_angle_as_r3_rotation_matrix(two_theta) R_ntt = s0n.axis_and_angle_as_r3_rotation_matrix(-two_theta) # now decompose to e3, e2, e1 sol_plus = rotation_decomposition.solve_r3_rotation_for_angles_given_axes( R_ptt, e3, e2, e1, return_both_solutions=True, deg=True) sol_minus = rotation_decomposition.solve_r3_rotation_for_angles_given_axes( R_ntt, e3, e2, e1, return_both_solutions=True, deg=True) solutions = [] if sol_plus: solutions.extend(sol_plus) if sol_minus: solutions.extend(sol_minus) if not solutions: sys.exit("Impossible two theta: %.3f," % (two_theta * 180.0 / math.pi)) logger.info("Maximum two theta: %.3f," % (two_theta * 180.0 / math.pi)) logger.info("%d solutions found" % len(solutions)) names = tuple([ n.replace("GON_", "").lower() for n in expt.goniometer.get_names() ]) logger.info(" %8s %8s %8s coverage expt.expt" % names) self.write_expt(experiments, "solution_0.expt") for j, s in enumerate(solutions): expt.goniometer.set_angles(s) if model_shadow: obs, shadow = self.predict_to_miller_set_with_shadow( expt, resolution) else: obs = self.predict_to_miller_set(expt, resolution) new = missing.common_set(obs) fout = "solution_%d.expt" % (j + 1) f = len(new.indices()) / len(missing.indices()) logger.info("%8.3f %8.3f %8.3f %4.2f %s" % (s[0], s[1], s[2], f, fout)) self.write_expt(experiments, fout) def make_scan_360(self, scan): epochs = scan.get_epochs() exposure_times = scan.get_exposure_times() image_range = scan.get_image_range() oscillation = scan.get_oscillation() current = 1 + image_range[1] - image_range[0] turn = int(round(360.0 / oscillation[1])) extra = turn - current for j in range(extra): epochs.append(0.0) exposure_times.append(0.0) image_range = image_range[0], image_range[1] + extra scan.set_image_range(image_range) scan.set_epochs(epochs) scan.set_exposure_times(exposure_times) return scan def predict_to_miller_set(self, expt, resolution): predicted = flex.reflection_table.from_predictions(expt, dmin=resolution) hkl = predicted["miller_index"] # now get a full set of all unique miller indices obs = miller.set( crystal_symmetry=crystal.symmetry( space_group=expt.crystal.get_space_group(), unit_cell=expt.crystal.get_unit_cell(), ), anomalous_flag=True, indices=hkl, ).unique_under_symmetry() return obs def predict_to_miller_set_with_shadow(self, expt, resolution): predicted = flex.reflection_table.from_predictions(expt, dmin=resolution) # transmogrify this to an ExperimentList from an Experiment experiments = ExperimentList() experiments.append(expt) predicted["id"] = flex.int(predicted.size(), 0) shadowed = filter_shadowed_reflections(experiments, predicted, experiment_goniometer=True) predicted = predicted.select(~shadowed) hkl = predicted["miller_index"] # now get a full set of all unique miller indices obs = miller.set( crystal_symmetry=crystal.symmetry( space_group=expt.crystal.get_space_group(), unit_cell=expt.crystal.get_unit_cell(), ), anomalous_flag=True, indices=hkl, ).unique_under_symmetry() return obs, shadowed def write_expt(self, experiments, filename): experiments.as_file(filename)
def run(args): usage = "dev.dials.csv [options] imported.expt strong.refl output.csv=rl.csv" parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, check_format=False, ) params, options = parser.parse_args(show_diff_phil=False) reflections, experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments) if not experiments or not reflections: parser.print_help() exit(0) spots = [] for reflection in reflections: unique_ids = set(reflection["id"]) for unique_id in sorted(unique_ids): spots.append(reflection.select(reflection["id"] == unique_id)) if not reflection: # If there are no reflections then export an empty list spots.append(reflection) assert len(experiments) == len(spots) if params.output.compress: fout = gzip.GzipFile(params.output.csv, "w") if six.PY3: # GzipFile() always provides binary access only. # Replace the file object with one that allows writing text: fout = io.TextIOWrapper(fout) # Rely on garbage collection to close the underlying GzipFile. else: fout = open(params.output.csv, "w") fout.write("# x,y,z,experiment_id,imageset_id\n") dp = params.output.dp if dp <= 0: fmt = "%f,%f,%f,%d,%d\n" else: fmt = "%%.%df,%%.%df,%%.%df,%%d,%%d\n" % (dp, dp, dp) print("Using format:", fmt.strip()) for k, (expt, refl) in enumerate(zip(experiments, spots)): if "imageset_id" not in refl: refl["imageset_id"] = refl["id"] refl.centroid_px_to_mm(ExperimentList([expt])) refl.map_centroids_to_reciprocal_space(ExperimentList([expt])) rlp = refl["rlp"] for _rlp in rlp: fout.write(fmt % (_rlp[0], _rlp[1], _rlp[2], k, k)) print("Appended %d spots to %s" % (len(rlp), params.output.csv)) fout.close()
class Script(object): '''A class for running the script.''' def __init__(self): from dials.util.options import OptionParser import libtbx.load_env usage = 'usage: %s [options] experiments.json indexed.pickle' \ % libtbx.env.dispatcher_name self.parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message, check_format=False, read_experiments=True, read_reflections=True) def run(self): from dials.array_family import flex # import dependency from scitbx import matrix from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections params, options = self.parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if len(experiments) == 0: self.parser.print_help() return if len(reflections) != 1: self.parser.print_help() return reflections = reflections[0] print 'Read %d reflections' % len(reflections) indexed = reflections.select( reflections.get_flags(reflections.flags.indexed)) print 'Kept %d indexed reflections' % len(indexed) for name in sorted(indexed.keys()): print 'Found column %s' % name for reflection in indexed[:3]: print reflection # verify that these experiments correspond to exactly one imageset, one # detector, one beam (obviously) for experiment in experiments[1:]: assert experiment.imageset == experiments[0].imageset assert experiment.beam == experiments[0].beam assert experiment.detector == experiments[0].detector # now perform some calculations - the only things different from one # experiment to the next will be crystal models crystals = [experiment.crystal for experiment in experiments] detector = experiments[0].detector beam = experiments[0].beam imageset = experiments[0].imageset # derived quantities wavelength = beam.get_wavelength() s0 = matrix.col(beam.get_s0()) # in here do some jiggery-pokery to cope with this being interpreted as # a rotation image in here i.e. if scan is not None; derive goniometer # matrix else set this to identity scan = experiments[0].scan goniometer = experiments[0].goniometer if scan and goniometer: angle = scan.get_angle_from_array_index( 0.5 * sum(imageset.get_array_range())) axis = matrix.col(goniometer.get_rotation_axis_datum()) F = matrix.sqr(goniometer.get_fixed_rotation()) S = matrix.sqr(goniometer.get_setting_rotation()) R = S * axis.axis_and_angle_as_r3_rotation_matrix(angle, deg=True) * F else: R = matrix.sqr((1, 0, 0, 0, 1, 0, 0, 0, 1)) assert (len(detector) == 1)
class Script: """A class for running the script.""" def __init__(self): """Initialise the script.""" # The script usage usage = ("usage: dials.predict [options] [param.phil] " "{sequence.expt | image1.file [image2.file ...]}") # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, epilog=help_message, check_format=True, read_experiments=True, ) def run(self, args=None): """Execute the script.""" # Parse the command line params, options = self.parser.parse_args(args, show_diff_phil=True) # Check the number of experiments experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: self.parser.print_help() return predicted_all = flex.reflection_table() for i_expt, expt in enumerate(experiments): if params.buffer_size > 0: # Hack to make the predicter predict reflections outside of the range # of the scan scan = expt.scan image_range = scan.get_image_range() oscillation = scan.get_oscillation() scan.set_image_range(( image_range[0] - params.buffer_size, image_range[1] + params.buffer_size, )) scan.set_oscillation(( oscillation[0] - params.buffer_size * oscillation[1], oscillation[1], )) # Populate the reflection table with predictions predicted = flex.reflection_table.from_predictions( expt, force_static=params.force_static, dmin=params.d_min) predicted["id"] = flex.int(len(predicted), i_expt) predicted_all.extend(predicted) # if we are not ignoring shadows, look for reflections in the masked # region, see https://github.com/dials/dials/issues/349 if not params.ignore_shadows: shadowed = filter_shadowed_reflections(experiments, predicted_all, experiment_goniometer=True) predicted_all = predicted_all.select(~shadowed) try: predicted_all.compute_bbox(experiments) except Exception: pass # Save the reflections to file Command.start( f"Saving {len(predicted_all)} reflections to {params.output}") predicted_all.as_file(params.output) Command.end( f"Saved {len(predicted_all)} reflections to {params.output}")
def run(args): import libtbx.load_env from libtbx.utils import Sorry usage = "%s [options] experiments.json indexed.pickle" % libtbx.env.dispatcher_name parser = OptionParser(usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0 and len(reflections) == 0: parser.print_help() return elif len(experiments.crystals()) > 1: raise Sorry("Only one crystal can be processed at a time") if params.change_of_basis_op is None: raise Sorry("Please provide a change_of_basis_op.") reference_crystal = None if params.reference is not None: from dxtbx.serialize import load reference_experiments = load.experiment_list(params.reference, check_format=False) assert len(reference_experiments.crystals()) == 1 reference_crystal = reference_experiments.crystals()[0] if len(experiments) and params.change_of_basis_op is libtbx.Auto: if reference_crystal is not None: from dials.algorithms.indexing.compare_orientation_matrices \ import difference_rotation_matrix_axis_angle cryst = experiments.crystals()[0] R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle( cryst, reference_crystal) print "Change of basis op: %s" % change_of_basis_op print "Rotation matrix to transform input crystal to reference::" print R.mathematica_form(format="%.3f", one_row_per_line=True) print "Rotation of %.3f degrees" % angle, "about axis (%.3f, %.3f, %.3f)" % axis elif len(reflections): assert len(reflections) == 1 # always re-map reflections to reciprocal space from dials.algorithms.indexing import indexer refl_copy = flex.reflection_table() for i, imageset in enumerate(experiments.imagesets()): if 'imageset_id' in reflections[0]: sel = (reflections[0]['imageset_id'] == i) else: sel = (reflections[0]['id'] == i) refl = indexer.indexer_base.map_spots_pixel_to_mm_rad( reflections[0].select(sel), imageset.get_detector(), imageset.get_scan()) indexer.indexer_base.map_centroids_to_reciprocal_space( refl, imageset.get_detector(), imageset.get_beam(), imageset.get_goniometer()) refl_copy.extend(refl) # index the reflection list using the input experiments list refl_copy['id'] = flex.int(len(refl_copy), -1) from dials.algorithms.indexing import index_reflections index_reflections(refl_copy, experiments, tolerance=0.2) hkl_expt = refl_copy['miller_index'] hkl_input = reflections[0]['miller_index'] change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt) # reset experiments list since we don't want to reindex this experiments = [] else: change_of_basis_op = sgtbx.change_of_basis_op( params.change_of_basis_op) if len(experiments): experiment = experiments[0] cryst_orig = copy.deepcopy(experiment.crystal) cryst_reindexed = cryst_orig.change_basis(change_of_basis_op) if params.space_group is not None: a, b, c = cryst_reindexed.get_real_space_vectors() cryst_reindexed = crystal_model( a, b, c, space_group=params.space_group.group()) experiment.crystal.update(cryst_reindexed) print "Old crystal:" print cryst_orig print print "New crystal:" print cryst_reindexed print print "Saving reindexed experimental models to %s" % params.output.experiments dump.experiment_list(experiments, params.output.experiments) if len(reflections): assert (len(reflections) == 1) reflections = reflections[0] miller_indices = reflections['miller_index'] if params.hkl_offset is not None: h, k, l = miller_indices.as_vec3_double().parts() h += params.hkl_offset[0] k += params.hkl_offset[1] l += params.hkl_offset[2] miller_indices = flex.miller_index(h.iround(), k.iround(), l.iround()) non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices( miller_indices) if non_integral_indices.size() > 0: print "Removing %i/%i reflections (change of basis results in non-integral indices)" % ( non_integral_indices.size(), miller_indices.size()) sel = flex.bool(miller_indices.size(), True) sel.set_selected(non_integral_indices, False) miller_indices_reindexed = change_of_basis_op.apply( miller_indices.select(sel)) reflections['miller_index'].set_selected(sel, miller_indices_reindexed) reflections['miller_index'].set_selected(~sel, (0, 0, 0)) print "Saving reindexed reflections to %s" % params.output.reflections easy_pickle.dump(params.output.reflections, reflections)
class Script(object): """A class for running the script.""" def __init__(self): """Initialise the script.""" from dials.util.options import OptionParser usage = ("usage: dials.slice_sequence [options] [param.phil] " "models.expt observations.refl") # Create the parser self.parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) def run(self, args=None): """Execute the script.""" from dials.util.options import reflections_and_experiments_from_files # Parse the command line params, options = self.parser.parse_args(args, show_diff_phil=True) reflections, experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments) # Try to load the models and data slice_exps = len(experiments) > 0 slice_refs = len(reflections) > 0 # Catch case of nothing to do if not slice_exps and not slice_refs: print("No suitable input provided") self.parser.print_help() return if reflections: if len(reflections) > 1: raise Sorry( "Only one reflections list can be imported at present") reflections = reflections[0] # calculate frame numbers if needed if experiments: reflections = calculate_frame_numbers(reflections, experiments) # if we still don't have the right column give up if "xyzobs.px.value" not in reflections: raise Sorry( "These reflections do not have frame numbers set, and " "there are no experiments provided to calculate these.") # set trivial case where no scan range is provided at all if not params.image_range: params.image_range = [None] # check if slicing into blocks if params.block_size is not None: if slice_exps: if len(experiments) > 1: raise Sorry( "For slicing into blocks please provide a single " "scan only") scan = experiments[0].scan # Having extracted the scan, calculate the blocks params.image_range = calculate_block_ranges( scan, params.block_size) # Do the slicing then recombine if slice_exps: sliced = [ slice_experiments(experiments, [sr])[0] for sr in params.image_range ] sliced_experiments = ExperimentList() for exp in sliced: sliced_experiments.append(exp) # slice reflections if present if slice_refs: sliced = [ slice_reflections(reflections, [sr]) for sr in params.image_range ] sliced_reflections = sliced[0] for i, rt in enumerate(sliced[1:]): rt["id"] += i + 1 # set id sliced_reflections.extend(rt) else: # slice each dataset into the requested subset if slice_exps: sliced_experiments = slice_experiments(experiments, params.image_range) if slice_refs: sliced_reflections = slice_reflections(reflections, params.image_range) # Save sliced experiments if slice_exps: output_experiments_filename = params.output.experiments_filename if output_experiments_filename is None: # take first filename as template bname = basename(params.input.experiments[0].filename) bname = splitext(bname)[0] if not bname: bname = "experiments" if len(params.image_range ) == 1 and params.image_range[0] is not None: ext = "_{0}_{1}.expt".format(*params.image_range[0]) else: ext = "_sliced.expt" output_experiments_filename = bname + ext print("Saving sliced experiments to {}".format( output_experiments_filename)) sliced_experiments.as_file(output_experiments_filename) # Save sliced reflections if slice_refs: output_reflections_filename = params.output.reflections_filename if output_reflections_filename is None: # take first filename as template bname = basename(params.input.reflections[0].filename) bname = splitext(bname)[0] if not bname: bname = "reflections" if len(params.image_range ) == 1 and params.image_range[0] is not None: ext = "_{0}_{1}.refl".format(*params.image_range[0]) else: ext = "_sliced.refl" output_reflections_filename = bname + ext print("Saving sliced reflections to {0}".format( output_reflections_filename)) sliced_reflections.as_file(output_reflections_filename) return
class Script(object): """A class for running the script.""" def __init__(self, phil=phil_scope): """Initialise the script.""" from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = ( "usage: %s [options] [param.phil] " "{models.expt | image1.file [image2.file ...]}" % libtbx.env.dispatcher_name ) # Initialise the base class self.parser = OptionParser( usage=usage, phil=phil, epilog=help_message, read_experiments_from_images=True, read_experiments=True, ) def run(self, args=None): """Execute the script.""" from dials.array_family import flex from dials.util.options import flatten_experiments from time import time from dials.util import log start_time = time() # Parse the command line params, options = self.parser.parse_args(args=args, show_diff_phil=False) if __name__ == "__main__": # Configure the logging log.config( params.verbosity, info=params.output.log, debug=params.output.debug_log ) from dials.util.version import dials_version logger.info(dials_version()) # Log the diff phil diff_phil = self.parser.diff_phil.as_str() if diff_phil != "": logger.info("The following parameters have been modified:\n") logger.info(diff_phil) # Ensure we have a data block experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: self.parser.print_help() return # Loop through all the imagesets and find the strong spots reflections = flex.reflection_table.from_observations(experiments, params) # Add n_signal column - before deleting shoeboxes from dials.algorithms.shoebox import MaskCode good = MaskCode.Foreground | MaskCode.Valid reflections["n_signal"] = reflections["shoebox"].count_mask_values(good) # Delete the shoeboxes if not params.output.shoeboxes: del reflections["shoebox"] # ascii spot count per image plot from dials.util.ascii_art import spot_counts_per_image_plot for i, experiment in enumerate(experiments): ascii_plot = spot_counts_per_image_plot( reflections.select(reflections["id"] == i) ) if len(ascii_plot): logger.info("\nHistogram of per-image spot count for imageset %i:" % i) logger.info(ascii_plot) # Save the reflections to file logger.info("\n" + "-" * 80) reflections.as_file(params.output.reflections) logger.info( "Saved {} reflections to {}".format( len(reflections), params.output.reflections ) ) # Save the experiments if params.output.experiments: logger.info("Saving experiments to {}".format(params.output.experiments)) experiments.as_file(params.output.experiments) # Print some per image statistics if params.per_image_statistics: from dials.algorithms.spot_finding import per_image_analysis from six.moves import cStringIO as StringIO s = StringIO() for i, experiment in enumerate(experiments): print("Number of centroids per image for imageset %i:" % i, file=s) imageset = experiment.imageset stats = per_image_analysis.stats_imageset( imageset, reflections.select(reflections["id"] == i), resolution_analysis=False, ) per_image_analysis.print_table(stats, out=s) logger.info(s.getvalue()) # Print the time logger.info("Time Taken: %f" % (time() - start_time)) if params.output.experiments: return experiments, reflections else: return reflections
def run(args=None): from dials.util import log from dials.util.options import OptionParser, reflections_and_experiments_from_files usage = "dials.rl_png [options] experiments.json observations.refl" parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(args) reflections, experiments = reflections_and_experiments_from_files( params.input.reflections, params.input.experiments) if len(experiments) == 0 or len(reflections) == 0: parser.print_help() exit(0) # Configure the logging log.config(logfile="dials.rl_png.log") # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil != "": logger.info("The following parameters have been modified:\n") logger.info(diff_phil) reflections = reflections[0] f = ReciprocalLatticePng(settings=params) f.load_models(experiments, reflections) rotation_axis = matrix.col(experiments[0].goniometer.get_rotation_axis()) s0 = matrix.col(experiments[0].beam.get_s0()) e1 = rotation_axis.normalize() e2 = s0.normalize() e3 = e1.cross(e2).normalize() f.viewer.plot("rl_rotation_axis.png", n=e1.elems) f.viewer.plot("rl_beam_vector", n=e2.elems) f.viewer.plot("rl_e3.png", n=e3.elems) n_solutions = params.basis_vector_search.n_solutions if experiments.crystals().count(None) < len(experiments): for i, c in enumerate(experiments.crystals()): A = matrix.sqr(c.get_A()) direct_matrix = A.inverse() a = direct_matrix[:3] b = direct_matrix[3:6] c = direct_matrix[6:9] prefix = "" if len(experiments.crystals()) > 1: prefix = "%i_" % (i + 1) f.viewer.plot(f"rl_{prefix}a.png", n=a) f.viewer.plot(f"rl_{prefix}b.png", n=b) f.viewer.plot(f"rl_{prefix}c.png", n=c) elif n_solutions: if "imageset_id" not in reflections: reflections["imageset_id"] = reflections["id"] reflections.centroid_px_to_mm(experiments) reflections.map_centroids_to_reciprocal_space(experiments) if params.d_min is not None: d_spacings = 1 / reflections["rlp"].norms() sel = d_spacings > params.d_min reflections = reflections.select(sel) # derive a max_cell from mm spots max_cell = find_max_cell(reflections, max_cell_multiplier=1.3, step_size=45).max_cell result = run_dps(experiments[0], reflections, max_cell) if result: solutions = [matrix.col(v) for v in result["solutions"]] for i in range(min(n_solutions, len(solutions))): v = solutions[i] f.viewer.plot(f"rl_solution_{i + 1}.png", n=v.elems)
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from dials.util.options import flatten_reflections from dials.util import log import libtbx.load_env usage = "%s [options] datablock.json reflections.pickle" % ( libtbx.env.dispatcher_name) parser = OptionParser(usage=usage, phil=phil_scope, read_datablocks=True, read_experiments=True, read_reflections=True, check_format=False, epilog=help_message) params, options = parser.parse_args() datablocks = flatten_datablocks(params.input.datablock) experiments = flatten_experiments(params.input.experiments) reflections = flatten_reflections(params.input.reflections) if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0: parser.print_help() exit(0) # Configure the logging log.config(info='dials.detect_blanks.log') # Log the diff phil diff_phil = parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) reflections = reflections[0] if len(datablocks) == 0 and len(experiments) > 0: imagesets = experiments.imagesets() else: imagesets = [] for datablock in datablocks: imagesets.extend(datablock.extract_imagesets()) assert len(imagesets) == 1 imageset = imagesets[0] scan = imageset.get_scan() integrated_sel = reflections.get_flags(reflections.flags.integrated) indexed_sel = reflections.get_flags(reflections.flags.indexed) centroid_outlier_sel = reflections.get_flags( reflections.flags.centroid_outlier) strong_sel = reflections.get_flags(reflections.flags.strong) indexed_sel &= (~centroid_outlier_sel) logger.info('Analysis of %i strong reflections:' % strong_sel.count(True)) strong_results = blank_counts_analysis( reflections.select(strong_sel), scan, phi_step=params.phi_step, fractional_loss=params.counts_fractional_loss) for blank_start, blank_end in strong_results['blank_regions']: logger.info('Potential blank images: %i -> %i' % (blank_start + 1, blank_end)) indexed_results = None if indexed_sel.count(True) > 0: logger.info('Analysis of %i indexed reflections:' % indexed_sel.count(True)) indexed_results = blank_counts_analysis( reflections.select(indexed_sel), scan, phi_step=params.phi_step, fractional_loss=params.counts_fractional_loss) for blank_start, blank_end in indexed_results['blank_regions']: logger.info('Potential blank images: %i -> %i' % (blank_start + 1, blank_end)) integrated_results = None if integrated_sel.count(True) > 0: logger.info('Analysis of %i integrated reflections:' % integrated_sel.count(True)) integrated_results = blank_integrated_analysis( reflections.select(integrated_sel), scan, phi_step=params.phi_step, fractional_loss=params.misigma_fractional_loss) for blank_start, blank_end in integrated_results['blank_regions']: logger.info('Potential blank images: %i -> %i' % (blank_start + 1, blank_end)) d = { 'strong': strong_results, 'indexed': indexed_results, 'integrated': integrated_results } if params.output.json is not None: import json with open(params.output.json, 'wb') as f: json.dump(d, f) if params.output.plot: from matplotlib import pyplot plots = [(strong_results, '-')] if indexed_results: plots.append((indexed_results, '--')) if integrated_results: plots.append((integrated_results, ':')) for results, linestyle in plots: xs = results['data'][0]['x'] ys = results['data'][0]['y'] xmax = max(xs) ymax = max(ys) xs = [x / xmax for x in xs] ys = [y / ymax for y in ys] blanks = results['data'][0]['blank'] pyplot.plot(xs, ys, color='blue', linestyle=linestyle) pyplot.plot(*zip(*[(x, y) for x, y, blank in zip(xs, ys, blanks) if blank]), color='red', linestyle=linestyle) pyplot.ylim(0) pyplot.show() pyplot.clf()
class Script(object): ''' The integration program. ''' def __init__(self): '''Initialise the script.''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] experiment.json" % libtbx.env.dispatcher_name # Create the parser self.parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message, read_experiments=True, read_reflections=True) def run(self): ''' Perform the integration. ''' from dials.util.command_line import heading from dials.util.options import flatten_reflections, flatten_experiments from dials.util import log from time import time from libtbx.utils import Sorry # Check the number of arguments is correct start_time = time() # Parse the command line params, options = self.parser.parse_args(show_diff_phil=False) reference = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(reference) == 0 and len(experiments) == 0: self.parser.print_help() return if len(reference) == 0: reference = None elif len(reference) != 1: raise Sorry('more than 1 reflection file was given') else: reference = reference[0] if len(experiments) == 0: raise Sorry('no experiment list was specified') # Save phil parameters if params.output.phil is not None: with open(params.output.phil, "w") as outfile: outfile.write(self.parser.diff_phil.as_str()) # Configure logging log.config(params.verbosity, info=params.output.log, debug=params.output.debug_log) from dials.util.version import dials_version logger.info(dials_version()) # Log the diff phil diff_phil = self.parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) # Print if we're using a mask for i, exp in enumerate(experiments): mask = exp.imageset.external_lookup.mask if mask.filename is not None: if mask.data: logger.info('Using external mask: %s' % mask.filename) logger.info(' Mask has %d pixels masked' % mask.data.count(False)) # Print the experimental models for i, exp in enumerate(experiments): logger.debug("Models for experiment %d" % i) logger.debug("") logger.debug(str(exp.beam)) logger.debug(str(exp.detector)) if exp.goniometer: logger.debug(str(exp.goniometer)) if exp.scan: logger.debug(str(exp.scan)) logger.debug(str(exp.crystal)) logger.info("=" * 80) logger.info("") logger.info(heading("Initialising")) logger.info("") # Load the data reference, rubbish = self.process_reference(reference) logger.info("") # Initialise the integrator from dials.algorithms.profile_model.factory import ProfileModelFactory from dials.algorithms.integration.integrator import IntegratorFactory from dials.array_family import flex # Modify experiment list if scan range is set. experiments, reference = self.split_for_scan_range( experiments, reference, params.scan_range) # Predict the reflections logger.info("") logger.info("=" * 80) logger.info("") logger.info(heading("Predicting reflections")) logger.info("") predicted = flex.reflection_table.from_predictions_multi( experiments, dmin=params.prediction.d_min, dmax=params.prediction.d_max, margin=params.prediction.margin, force_static=params.prediction.force_static) # Match reference with predicted if reference: matched, reference, unmatched = predicted.match_with_reference( reference) assert (len(matched) == len(predicted)) assert (matched.count(True) <= len(reference)) if matched.count(True) == 0: raise Sorry(''' Invalid input for reference reflections. Zero reference spots were matched to predictions ''') elif len(unmatched) != 0: logger.info('') logger.info('*' * 80) logger.info( 'Warning: %d reference spots were not matched to predictions' % (len(unmatched))) logger.info('*' * 80) logger.info('') rubbish.extend(unmatched) if len(experiments) > 1: # filter out any experiments without matched reference reflections # f_: filtered from dxtbx.model.experiment.experiment_list import ExperimentList f_reference = flex.reflection_table() f_predicted = flex.reflection_table() f_rubbish = flex.reflection_table() f_experiments = ExperimentList() good_expt_count = 0 def refl_extend(src, dest, eid): tmp = src.select(src['id'] == eid) tmp['id'] = flex.int(len(tmp), good_expt_count) dest.extend(tmp) for expt_id, experiment in enumerate(experiments): if len(reference.select(reference['id'] == expt_id)) != 0: refl_extend(reference, f_reference, expt_id) refl_extend(predicted, f_predicted, expt_id) refl_extend(rubbish, f_rubbish, expt_id) f_experiments.append(experiment) good_expt_count += 1 else: logger.info( "Removing experiment %d: no reference reflections matched to predictions" % expt_id) reference = f_reference predicted = f_predicted experiments = f_experiments rubbish = f_rubbish # Select a random sample of the predicted reflections if not params.sampling.integrate_all_reflections: predicted = self.sample_predictions(experiments, predicted, params) # Compute the profile model if (params.create_profile_model and reference is not None and "shoebox" in reference): experiments = ProfileModelFactory.create(params, experiments, reference) else: for expr in experiments: if expr.profile is None: raise Sorry('No profile information in experiment list') expr.profile.params = params.profile del reference # Compute the bounding box predicted.compute_bbox(experiments) # Create the integrator logger.info("") integrator = IntegratorFactory.create(params, experiments, predicted) # Integrate the reflections reflections = integrator.integrate() # Append rubbish data onto the end if rubbish is not None and params.output.include_bad_reference: mask = flex.bool(len(rubbish), True) rubbish.unset_flags(mask, rubbish.flags.integrated_sum) rubbish.unset_flags(mask, rubbish.flags.integrated_prf) rubbish.set_flags(mask, rubbish.flags.bad_reference) reflections.extend(rubbish) # Save the reflections self.save_reflections(reflections, params.output.reflections) self.save_experiments(experiments, params.output.experiments) # Write a report if requested if params.output.report is not None: integrator.report().as_file(params.output.report) # Print the total time taken logger.info("\nTotal time taken: %f" % (time() - start_time)) def process_reference(self, reference): ''' Load the reference spots. ''' from dials.array_family import flex from time import time from libtbx.utils import Sorry if reference is None: return None, None st = time() assert ("miller_index" in reference) assert ("id" in reference) logger.info('Processing reference reflections') logger.info(' read %d strong spots' % len(reference)) mask = reference.get_flags(reference.flags.indexed) rubbish = reference.select(mask == False) if mask.count(False) > 0: reference.del_selected(mask == False) logger.info(' removing %d unindexed reflections' % mask.count(True)) if len(reference) == 0: raise Sorry(''' Invalid input for reference reflections. Expected > %d indexed spots, got %d ''' % (0, len(reference))) mask = reference.get_flags(reference.flags.centroid_outlier) if mask.count(True) > 0: rubbish.extend(reference.select(mask)) reference.del_selected(mask) logger.info( ' removing %d reflections marked as centroid outliers' % mask.count(True)) mask = reference['miller_index'] == (0, 0, 0) if mask.count(True) > 0: rubbish.extend(reference.select(mask)) reference.del_selected(mask) logger.info(' removing %d reflections with hkl (0,0,0)' % mask.count(True)) mask = reference['id'] < 0 if mask.count(True) > 0: raise Sorry(''' Invalid input for reference reflections. %d reference spots have an invalid experiment id ''' % mask.count(True)) logger.info(' using %d indexed reflections' % len(reference)) logger.info(' found %d junk reflections' % len(rubbish)) logger.info(' time taken: %g' % (time() - st)) return reference, rubbish def save_reflections(self, reflections, filename): ''' Save the reflections to file. ''' from time import time st = time() logger.info('Saving %d reflections to %s' % (len(reflections), filename)) reflections.as_pickle(filename) logger.info(' time taken: %g' % (time() - st)) def save_experiments(self, experiments, filename): ''' Save the profile model parameters. ''' from time import time from dxtbx.model.experiment.experiment_list import ExperimentListDumper st = time() logger.info('Saving the experiments to %s' % filename) dump = ExperimentListDumper(experiments) with open(filename, "w") as outfile: outfile.write(dump.as_json()) logger.info(' time taken: %g' % (time() - st)) def sample_predictions(self, experiments, predicted, params): ''' Select a random sample of the predicted reflections to integrate. ''' from dials.array_family import flex nref_per_degree = params.sampling.reflections_per_degree min_sample_size = params.sampling.minimum_sample_size max_sample_size = params.sampling.maximum_sample_size # this code is very similar to David's code in algorithms/refinement/reflection_manager.py! # constants from math import pi RAD2DEG = 180. / pi DEG2RAD = pi / 180. working_isel = flex.size_t() for iexp, exp in enumerate(experiments): sel = predicted['id'] == iexp isel = sel.iselection() #refs = self._reflections.select(sel) nrefs = sample_size = len(isel) # set sample size according to nref_per_degree (per experiment) if exp.scan and nref_per_degree: sweep_range_rad = exp.scan.get_oscillation_range(deg=False) width = abs(sweep_range_rad[1] - sweep_range_rad[0]) * RAD2DEG sample_size = int(nref_per_degree * width) else: sweep_range_rad = None # adjust sample size if below the chosen limit sample_size = max(sample_size, min_sample_size) # set maximum sample size if requested if max_sample_size: sample_size = min(sample_size, max_sample_size) # determine subset and collect indices if sample_size < nrefs: isel = isel.select(flex.random_selection(nrefs, sample_size)) working_isel.extend(isel) # create subset return predicted.select(working_isel) def split_for_scan_range(self, experiments, reference, scan_range): ''' Update experiments when scan range is set. ''' from dxtbx.model.experiment.experiment_list import ExperimentList from dxtbx.model.experiment.experiment_list import Experiment from dials.array_family import flex # Only do anything is the scan range is set if scan_range is not None and len(scan_range) > 0: # Ensure that all experiments have the same imageset and scan iset = [e.imageset for e in experiments] scan = [e.scan for e in experiments] assert (all(x == iset[0] for x in iset)) assert (all(x == scan[0] for x in scan)) # Get the imageset and scan iset = experiments[0].imageset scan = experiments[0].scan # Get the array range if scan is not None: frame10, frame11 = scan.get_array_range() assert (scan.get_num_images() == len(iset)) else: frame10, frame11 = (0, len(iset)) # Create the new lists new_experiments = ExperimentList() new_reference_all = reference.split_by_experiment_id() new_reference = flex.reflection_table() for i in range(len(new_reference_all) - len(experiments)): new_reference_all.append(flex.reflection_table()) assert (len(new_reference_all) == len(experiments)) # Loop through all the scan ranges and create a new experiment list with # the requested scan ranges. for frame00, frame01 in scan_range: assert (frame01 > frame00) assert (frame00 >= frame10) assert (frame01 <= frame11) index0 = frame00 - frame10 index1 = index0 + (frame01 - frame00) assert (index0 < index1) assert (index0 >= 0) assert (index1 <= len(iset)) new_iset = iset[index0:index1] if scan is None: new_scan = None else: new_scan = scan[index0:index1] for i, e1 in enumerate(experiments): e2 = Experiment() e2.beam = e1.beam e2.detector = e1.detector e2.goniometer = e1.goniometer e2.crystal = e1.crystal e2.imageset = new_iset e2.scan = new_scan new_reference_all[i]['id'] = flex.int( len(new_reference_all[i]), len(new_experiments)) new_reference.extend(new_reference_all[i]) new_experiments.append(e2) experiments = new_experiments reference = new_reference # Print some information logger.info( 'Modified experiment list to integrate over requested scan range' ) for frame00, frame01 in scan_range: logger.info(' scan_range = %d -> %d' % (frame00, frame01)) logger.info('') # Return the experiments return experiments, reference
def run(args): from dials.util.options import OptionParser from dials.util.options import flatten_experiments import libtbx.load_env usage = "%s [options] datablock.json" %( libtbx.env.dispatcher_name) parser = OptionParser( usage=usage, phil=phil_scope, read_experiments=True, check_format=False, epilog=help_message) params, options = parser.parse_args(show_diff_phil=True) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0: parser.print_help() exit(0) imagesets = experiments.imagesets() expt = experiments[0] frame = None if len(params.align.crystal.vector): assert len(params.align.crystal.vector) %2 == 0 vectors = [] name_to_vectors = { 'a': (a, 'direct'), 'b': (b, 'direct'), 'c': (c, 'direct'), 'a*': (a_star, 'reciprocal'), 'b*': (b_star, 'reciprocal'), 'c*': (c_star, 'reciprocal'), } for v in params.align.crystal.vector: v = v.strip() if v in name_to_vectors: v, frame_ = name_to_vectors[v] assert frame is None or frame == frame_ frame = frame_ else: v = v.replace(',', ' ').strip().split() assert len(v) == 3 v = matrix.col([float(v_) for v_ in v]) if frame is None: frame = params.align.crystal.frame vectors.append(v) vectors = [(vectors[2*i], vectors[2*i+1]) for i in range(len(vectors)//2)] else: frame = 'reciprocal' vectors = ((a_star, b_star), # a*, b* (a_star, c_star), # a*, c* (b_star, a_star), # b*, a* (b_star, c_star), # b*, c* (c_star, a_star), # c*, a* (c_star, b_star), # c*, b* ) result = align_crystal(expt, vectors, frame=frame, mode=params.align.mode) result.show() if params.output.json is not None: result.as_json(filename=params.output.json)
class Script(object): '''A class for running the script.''' def __init__(self): '''Initialise the script.''' from dials.util.options import OptionParser import libtbx.load_env # The script usage usage = "usage: %s [options] [param.phil] " \ "experiments.json reflections.pickle" \ % libtbx.env.dispatcher_name # Create the parser self.parser = OptionParser(usage=usage, phil=working_phil, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message) @staticmethod def check_input(reflections): '''Check the input is suitable for refinement. So far just check keys in the reflection table. Maybe later check experiments have overlapping models etc.''' msg = "The supplied reflection table does not have the required data " + \ "column: {0}" for key in ["xyzobs.mm.value", "xyzobs.mm.variance"]: if key not in reflections: msg = msg.format(key) raise Sorry(msg) # FIXME add other things to be checked here return @staticmethod def combine_crystals(experiments): '''Replace all crystals in the experiments list with the first crystal''' from dxtbx.model.experiment_list import Experiment, ExperimentList new_experiments = ExperimentList() ref_crystal = experiments[0].crystal for exp in experiments: new_experiments.append( Experiment(beam=exp.beam, detector=exp.detector, scan=exp.scan, goniometer=exp.goniometer, crystal=ref_crystal, imageset=exp.imageset)) return new_experiments @staticmethod def filter_integrated_centroids(reflections): '''Filter reflections to include only those with the integrated and the strong flag set, but only if there are apparently some integrated reflections''' orig_len = len(reflections) inc = flex.bool(orig_len, False) mask = reflections.get_flags(reflections.flags.integrated) if mask.count(True) == 0: return reflections reflections = reflections.select(mask) mask = reflections.get_flags(reflections.flags.strong) reflections = reflections.select(mask) logger.info( '{0} out of {1} reflections remain after filtering to keep only strong' ' and integrated centroids'.format(len(reflections), orig_len)) return reflections @staticmethod def convert_to_P1(reflections, experiments): '''Convert the input crystals to P 1 and reindex the reflections''' from cctbx.sgtbx import space_group for iexp, exp in enumerate(experiments): sel = reflections['id'] == iexp xl = exp.crystal sg = xl.get_space_group() op = sg.info().change_of_basis_op_to_primitive_setting() exp.crystal = xl.change_basis(op) exp.crystal.set_space_group(space_group("P 1")) hkl_reindexed = op.apply(reflections['miller_index'].select(sel)) reflections['miller_index'].set_selected(sel, hkl_reindexed) return reflections, experiments @staticmethod def create_refiner(params, reflections, experiments): from dials.algorithms.refinement.parameterisation.crystal_parameters import \ CrystalUnitCellParameterisation from dials.algorithms.refinement.parameterisation.parameter_report import \ ParameterReporter from dials.algorithms.refinement.two_theta_refiner import \ TwoThetaReflectionManager, TwoThetaTarget, TwoThetaExperimentsPredictor, \ TwoThetaPredictionParameterisation verb = params.refinement.verbosity # Only parameterise the crystal unit cell det_params = None beam_params = None xlo_params = None xluc_params = [] for icrystal, crystal in enumerate(experiments.crystals()): exp_ids = experiments.indices(crystal) xluc_params.append( CrystalUnitCellParameterisation(crystal, experiment_ids=exp_ids)) # Two theta prediction equation parameterisation pred_param = TwoThetaPredictionParameterisation( experiments, det_params, beam_params, xlo_params, xluc_params) param_reporter = ParameterReporter(det_params, beam_params, xlo_params, xluc_params) # ReflectionManager, currently without outlier rejection # Note: If not all reflections are used, then the filtering must be # communicated to generate_cif/mmcif() to be included in the CIF file! refman = TwoThetaReflectionManager(reflections, experiments, outlier_detector=None, verbosity=verb) # Reflection predictor ref_predictor = TwoThetaExperimentsPredictor(experiments) # Two theta target target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param) # Do a correlation plot? tpc = params.output.correlation_plot.filename is not None # Minimisation engine - FIXME not many choices exposed yet. Do we want # more cowbell? from dials.algorithms.refinement.engine \ import LevenbergMarquardtIterations as Refinery refinery = Refinery(target=target, prediction_parameterisation=pred_param, log=None, verbosity=verb, track_step=False, track_gradient=False, track_parameter_correlation=tpc, max_iterations=20) # Refiner from dials.algorithms.refinement.refiner import Refiner refiner = Refiner(reflections=reflections, experiments=experiments, pred_param=pred_param, param_reporter=param_reporter, refman=refman, target=target, refinery=refinery, verbosity=verb) return refiner @staticmethod def cell_param_table(crystal): '''Construct a table of cell parameters and their ESDs''' from libtbx.table_utils import simple_table cell = crystal.get_unit_cell().parameters() esd = crystal.get_cell_parameter_sd() vol = crystal.get_unit_cell().volume() vol_esd = crystal.get_cell_volume_sd() header = ["Parameter", "Value", "Estimated sd"] rows = [] names = ["a", "b", "c", "alpha", "beta", "gamma"] for n, p, e in zip(names, cell, esd): rows.append([n, "%9.5f" % p, "%9.5f" % e]) rows.append(["\nvolume", "\n%9.5f" % vol, "\n%9.5f" % vol_esd]) st = simple_table(rows, header) return st.format() @staticmethod def generate_p4p(crystal, beam, file): logger.info('Saving P4P info to %s' % file) cell = crystal.get_unit_cell().parameters() esd = crystal.get_cell_parameter_sd() vol = crystal.get_unit_cell().volume() vol_esd = crystal.get_cell_volume_sd() open(file, 'w').write('\n'.join([ 'TITLE Auto-generated .p4p file from dials.two_theta_refine', 'CELL %.4f %.4f %.4f %.4f %.4f %.4f %.4f' % tuple(cell + (vol, )), 'CELLSD %.4f %.4f %.4f %.4f %.4f %.4f %.4f' % tuple(esd + (vol_esd, )), 'SOURCE SYNCH %.6f' % beam.get_wavelength(), '' ])) return @staticmethod def generate_cif(crystal, refiner, file): logger.info('Saving CIF information to %s' % file) from cctbx import miller import datetime import iotbx.cif.model import math block = iotbx.cif.model.block() block["_audit_creation_method"] = dials_version() block["_audit_creation_date"] = datetime.date.today().isoformat() # block["_publ_section_references"] = '' # once there is a reference... for cell, esd, cifname in zip( crystal.get_unit_cell().parameters(), crystal.get_cell_parameter_sd(), [ 'length_a', 'length_b', 'length_c', 'angle_alpha', 'angle_beta', 'angle_gamma' ]): block['_cell_%s' % cifname] = format_float_with_standard_uncertainty(cell, esd) block['_cell_volume'] = format_float_with_standard_uncertainty( crystal.get_unit_cell().volume(), crystal.get_cell_volume_sd()) used_reflections = refiner.get_matches() block['_cell_measurement_reflns_used'] = len(used_reflections) block['_cell_measurement_theta_min'] = flex.min( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 block['_cell_measurement_theta_max'] = flex.max( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 block['_diffrn_reflns_number'] = len(used_reflections) miller_span = miller.index_span(used_reflections['miller_index']) min_h, min_k, min_l = miller_span.min() max_h, max_k, max_l = miller_span.max() block['_diffrn_reflns_limit_h_min'] = min_h block['_diffrn_reflns_limit_h_max'] = max_h block['_diffrn_reflns_limit_k_min'] = min_k block['_diffrn_reflns_limit_k_max'] = max_k block['_diffrn_reflns_limit_l_min'] = min_l block['_diffrn_reflns_limit_l_max'] = max_l block['_diffrn_reflns_theta_min'] = flex.min( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 block['_diffrn_reflns_theta_max'] = flex.max( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 cif = iotbx.cif.model.cif() cif['two_theta_refine'] = block with open(file, 'w') as fh: cif.show(out=fh) @staticmethod def generate_mmcif(crystal, refiner, file): logger.info('Saving mmCIF information to %s' % file) from cctbx import miller import datetime import iotbx.cif.model import math block = iotbx.cif.model.block() block["_audit.creation_method"] = dials_version() block["_audit.creation_date"] = datetime.date.today().isoformat() # block["_publ.section_references"] = '' # once there is a reference... for cell, esd, cifname in zip( crystal.get_unit_cell().parameters(), crystal.get_cell_parameter_sd(), [ 'length_a', 'length_b', 'length_c', 'angle_alpha', 'angle_beta', 'angle_gamma' ]): block['_cell.%s' % cifname] = "%.8f" % cell block['_cell.%s_esd' % cifname] = "%.8f" % esd block['_cell.volume'] = "%f" % crystal.get_unit_cell().volume() block['_cell.volume_esd'] = "%f" % crystal.get_cell_volume_sd() used_reflections = refiner.get_matches() block['_cell_measurement.reflns_used'] = len(used_reflections) block['_cell_measurement.theta_min'] = flex.min( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 block['_cell_measurement.theta_max'] = flex.max( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 block['_diffrn_reflns.number'] = len(used_reflections) miller_span = miller.index_span(used_reflections['miller_index']) min_h, min_k, min_l = miller_span.min() max_h, max_k, max_l = miller_span.max() block['_diffrn_reflns.limit_h_min'] = min_h block['_diffrn_reflns.limit_h_max'] = max_h block['_diffrn_reflns.limit_k_min'] = min_k block['_diffrn_reflns.limit_k_max'] = max_k block['_diffrn_reflns.limit_l_min'] = min_l block['_diffrn_reflns.limit_l_max'] = max_l block['_diffrn_reflns.theta_min'] = flex.min( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 block['_diffrn_reflns.theta_max'] = flex.max( used_reflections['2theta_obs.rad']) * 180 / math.pi / 2 cif = iotbx.cif.model.cif() cif['two_theta_refine'] = block with open(file, 'w') as fh: cif.show(out=fh) def run(self): '''Execute the script.''' from dials.algorithms.refinement.two_theta_refiner import \ TwoThetaReflectionManager, TwoThetaTarget, \ TwoThetaPredictionParameterisation start_time = time() # Parse the command line params, options = self.parser.parse_args(show_diff_phil=False) # set up global experiments and reflections lists from dials.array_family import flex reflections = flex.reflection_table() global_id = 0 from dxtbx.model.experiment_list import ExperimentList experiments = ExperimentList() # loop through the input, building up the global lists nrefs_per_exp = [] for ref_wrapper, exp_wrapper in zip(params.input.reflections, params.input.experiments): refs = ref_wrapper.data exps = exp_wrapper.data for i, exp in enumerate(exps): sel = refs['id'] == i sub_ref = refs.select(sel) nrefs_per_exp.append(len(sub_ref)) sub_ref['id'] = flex.int(len(sub_ref), global_id) reflections.extend(sub_ref) experiments.append(exp) global_id += 1 # Try to load the models and data nexp = len(experiments) if nexp == 0: print "No Experiments found in the input" self.parser.print_help() return if len(reflections) == 0: print "No reflection data found in the input" self.parser.print_help() return self.check_input(reflections) # Configure the logging log.config(info=params.output.log, debug=params.output.debug_log) logger.info(dials_version()) # Log the diff phil diff_phil = self.parser.diff_phil.as_str() if diff_phil is not '': logger.info('The following parameters have been modified:\n') logger.info(diff_phil) # Convert to P 1? if params.refinement.triclinic: reflections, experiments = self.convert_to_P1( reflections, experiments) # Combine crystals? if params.refinement.combine_crystal_models and len(experiments) > 1: logger.info('Combining {0} crystal models'.format( len(experiments))) experiments = self.combine_crystals(experiments) # Filter integrated centroids? if params.refinement.filter_integrated_centroids: reflections = self.filter_integrated_centroids(reflections) # Get the refiner logger.info('Configuring refiner') refiner = self.create_refiner(params, reflections, experiments) # Refine the geometry if nexp == 1: logger.info('Performing refinement of a single Experiment...') else: logger.info( 'Performing refinement of {0} Experiments...'.format(nexp)) # Refine and get the refinement history history = refiner.run() # get the refined experiments experiments = refiner.get_experiments() crystals = experiments.crystals() if len(crystals) == 1: # output the refined model for information logger.info('') logger.info('Final refined crystal model:') logger.info(crystals[0]) logger.info(self.cell_param_table(crystals[0])) # Save the refined experiments to file output_experiments_filename = params.output.experiments logger.info('Saving refined experiments to {0}'.format( output_experiments_filename)) from dxtbx.model.experiment_list import ExperimentListDumper dump = ExperimentListDumper(experiments) dump.as_json(output_experiments_filename) # Correlation plot if params.output.correlation_plot.filename is not None: from os.path import splitext root, ext = splitext(params.output.correlation_plot.filename) if not ext: ext = ".pdf" steps = params.output.correlation_plot.steps if steps is None: steps = [history.get_nrows() - 1] # extract individual column names or indices col_select = params.output.correlation_plot.col_select num_plots = 0 for step in steps: fname_base = root if len(steps) > 1: fname_base += "_step%02d" % step corrmats, labels = refiner.get_parameter_correlation_matrix( step, col_select) if [corrmats, labels].count(None) == 0: from dials.algorithms.refinement.refinement_helpers import corrgram for resid_name, corrmat in corrmats.items(): plot_fname = fname_base + ext plt = corrgram(corrmat, labels) if plt is not None: logger.info( 'Saving parameter correlation plot to {}'. format(plot_fname)) plt.savefig(plot_fname) plt.close() num_plots += 1 mat_fname = fname_base + ".pickle" with open(mat_fname, 'wb') as handle: for k, corrmat in corrmats.items(): corrmats[k] = corrmat.as_scitbx_matrix() logger.info( 'Saving parameter correlation matrices to {0}'. format(mat_fname)) pickle.dump({ 'corrmats': corrmats, 'labels': labels }, handle) if num_plots == 0: msg = "Sorry, no parameter correlation plots were produced. Please set " \ "track_parameter_correlation=True to ensure correlations are " \ "tracked, and make sure correlation_plot.col_select is valid." logger.info(msg) if params.output.cif is not None: self.generate_cif(crystals[0], refiner, file=params.output.cif) if params.output.p4p is not None: self.generate_p4p(crystals[0], experiments[0].beam, file=params.output.p4p) if params.output.mmcif is not None: self.generate_mmcif(crystals[0], refiner, file=params.output.mmcif) # Log the total time taken logger.info("\nTotal time taken: {0:.2f}s".format(time() - start_time))