示例#1
0
    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 logging import info
        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
            info("Modified experiment list to integrate over requested scan range")
            for frame00, frame01 in scan_range:
                info(" scan_range = %d -> %d" % (frame00, frame01))
            info("")

        # Return the experiments
        return experiments, reference
示例#2
0
文件: nx_mx.py 项目: hackerlank/dials
def load(entry, exp_index):
  from dxtbx.model.experiment.experiment_list import ExperimentList
  from dxtbx.model.experiment.experiment_list import Experiment

  print "Loading NXmx"

  # Check file contains the feature
  assert("features" in entry)
  assert(6 in entry['features'].value)

  experiment_list = ExperimentList()

  # Find all the experiments
  entries = find_nx_mx_entries(entry, ".")
  if len(entries) > 1:
    entries = sorted(entries, key=lambda x: x['dials/index'].value)

  assert(len(entries) == len(exp_index))
  for nxmx, name in zip(entries, exp_index):
    assert(nxmx.name == name)

  index = []
  rotations = []
  for name in exp_index:

    # Get the entry
    nxmx = entry.file[name]

    # Get the definition
    definition = nxmx['definition']
    assert(definition.value == 'NXmx')
    assert(definition.attrs['version'] == 1)

    # Get dials specific stuff
    nx_dials = get_nx_dials(nxmx, "dials")

    # Set index
    b = nx_dials['index'].attrs['source']
    d = nx_dials['index'].attrs['detector']
    if "goniometer" in nx_dials['index'].attrs:
      g = nx_dials['index'].attrs['goniometer']
    else:
      g = None
    if "scan" in nx_dials['index'].attrs:
      s = nx_dials['index'].attrs['scan']
    else:
      s = None
    c = nx_dials['index'].attrs['sample']
    index.append((b, d, g, s, c))

    # Get the original orientation (dials specific)
    transformations = get_nx_transformations(nx_dials,  "transformations")
    angle = transformations['angle'].value
    assert(transformations['angle'].attrs['transformation_type'] == 'rotation')
    axis = transformations['angle'].attrs['vector']
    assert(tuple(transformations['angle'].attrs['offset']) == (0, 0, 0))
    assert(transformations['angle'].attrs['offset_units'] == 'mm')
    assert(transformations['angle'].attrs['depends_on'] == '.')
    rotations.append((axis, angle))

    # Get the tmeplate and imageset
    try:
      template = list(nx_dials['template'])
      image_range = None
    except Exception:
      template = nx_dials['template'].value
      if template == "":
        template = None
      if "range" in nx_dials['template'].attrs:
        image_range = nx_dials['template'].attrs['range']
      else:
        image_range = None

    # Create the experiment
    experiment = Experiment()

    # Read the models
    experiment.beam = load_beam(nxmx)
    experiment.detector = load_detector(nxmx)
    experiment.goniometer = load_goniometer(nxmx)
    experiment.scan = load_scan(nxmx)
    experiment.crystal = load_crystal(nxmx)

    # Set the image range
    if image_range is not None and experiment.scan is not None:
      num = image_range[1] - image_range[0] + 1
      assert(num == len(experiment.scan))
      experiment.scan.set_image_range(image_range)

    # Return the experiment list
    experiment_list.append(experiment)

  # Convert from nexus beam direction
  experiment_list = convert_from_nexus_beam_direction(experiment_list,rotations)

  from collections import defaultdict
  beam = defaultdict(list)
  detector = defaultdict(list)
  goniometer = defaultdict(list)
  scan = defaultdict(list)
  crystal = defaultdict(list)
  for i, ind in enumerate(index):
    beam[ind[0]].append(i)
    detector[ind[1]].append(i)
    goniometer[ind[2]].append(i)
    scan[ind[3]].append(i)
    crystal[ind[4]].append(i)

  # Set all the shared beams
  for key, value in beam.iteritems():
    b1 = experiment_list[value[0]].beam
    assert(all(experiment_list[v].beam == b1 for v in value[1:]))
    for v in value[1:]:
      experiment_list[v].beam = b1
  # Set all the shared detectors
  for key, value in detector.iteritems():
    d1 = experiment_list[value[0]].detector
    assert(all(experiment_list[v].detector == d1 for v in value[1:]))
    for v in value[1:]:
      experiment_list[v].detector = d1
  # Set all the shared goniometer
  for key, value in goniometer.iteritems():
    g1 = experiment_list[value[0]].goniometer
    assert(all(experiment_list[v].goniometer == g1 for v in value[1:]))
    for v in value[1:]:
      experiment_list[v].goniometer = g1
  # Set all the shared scans
  for key, value in scan.iteritems():
    s1 = experiment_list[value[0]].scan
    assert(all(experiment_list[v].scan == s1 for v in value[1:]))
    for v in value[1:]:
      experiment_list[v].scan = s1
  # Set all the shared crystals
  for key, value in crystal.iteritems():
    c1 = experiment_list[value[0]].crystal
    assert(all(experiment_list[v].crystal == c1 for v in value[1:]))
    for v in value[1:]:
      experiment_list[v].crystal = c1

  return experiment_list
示例#3
0
    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