Example #1
0
    def get_maxima(self, threshold = 5.0):
      '''Run diffdump, printpeaks to get a list of diffraction maxima
      at their image positions, to allow for further analysis.'''

      if not self._image:
        raise RuntimeError, 'image not set'

      if not os.path.exists(self._image):
        raise RuntimeError, 'image %s does not exist' % \
              self._image

      dd = Diffdump()
      dd.set_image(self._image)
      header = dd.readheader()

      beam = header['raw_beam']
      pixel = header['pixel']

      template, directory = image2template_directory(self._image)
      image_number = image2image(os.path.split(self._image)[-1])

      spot_file = '%s.spt' % template_number2image(
          template, image_number)

      self.start()

      self.input('template "%s"' % template)
      self.input('directory "%s"' % directory)
      self.input('findspots local find %d file %s' % \
                 (image_number, spot_file))
      self.input('go')

      self.close_wait()

      self.check_for_errors()

      output = open(os.path.join(self.get_working_directory(),
                                 spot_file)).readlines()

      os.remove(os.path.join(self.get_working_directory(),
                             spot_file))

      peaks = []

      for record in output[3:-2]:
        lst = record.split()
        x = float(lst[0])
        y = float(lst[1])
        i = float(lst[4]) / float(lst[5])
        x /= pixel[0]
        y /= pixel[1]

        if i < threshold:
          continue

        # this is Mosflm right? Swap X & Y!!

        peaks.append((y, x, i))

      return peaks
Example #2
0
def get_template(f):

    global target_template

    if not is_image_name(f):
        return

    if is_xds_file(f):
        return

    # in here, check the permissions on the file...

    template = None
    directory = None

    if not os.access(f, os.R_OK):
        Debug.write('No read permission for %s' % f)

    try:
        template, directory = image2template_directory(f)
        template = os.path.join(directory, template)

        if target_template:
            if template not in target_template:
                return

    except Exception as e:
        Debug.write('Exception A: %s (%s)' % (str(e), f))
        Debug.write(traceback.format_exc())

    if template is None or directory is None:
        raise RuntimeError('template not recognised for %s' % f)

    return template
Example #3
0
    def _setup_from_image(self, image):
        """Configure myself from an image name."""
        template, directory = image2template_directory(image)
        self._fp_matching_images = find_matching_images(template, directory)

        # trim this down to only allowed images...
        if self._fp_wedge:
            start, end = self._fp_wedge
            images = []
            for j in self._fp_matching_images:
                if j < start or j > end:
                    continue
                images.append(j)
            self._fp_matching_images = images

        from xia2.Schema import load_imagesets

        imagesets = load_imagesets(
            template,
            directory,
            image_range=(self._fp_matching_images[0],
                         self._fp_matching_images[-1]),
        )
        assert len(imagesets) == 1, "multiple imagesets match %s" % template
        imageset = imagesets[0]

        self._setup_from_imageset(imageset)
Example #4
0
        def get_maxima(self, threshold=5.0):
            '''Run diffdump, printpeaks to get a list of diffraction maxima
      at their image positions, to allow for further analysis.'''

            if not self._image:
                raise RuntimeError('image not set')

            if not os.path.exists(self._image):
                raise RuntimeError('image %s does not exist' % \
                      self._image)

            dd = Diffdump()
            dd.set_image(self._image)
            header = dd.readheader()

            beam = header['raw_beam']
            pixel = header['pixel']

            template, directory = image2template_directory(self._image)
            image_number = image2image(os.path.split(self._image)[-1])

            spot_file = '%s.spt' % template_number2image(
                template, image_number)

            self.start()

            self.input('template "%s"' % template)
            self.input('directory "%s"' % directory)
            self.input('findspots local find %d file %s' % \
                       (image_number, spot_file))
            self.input('go')

            self.close_wait()

            self.check_for_errors()

            output = open(os.path.join(self.get_working_directory(),
                                       spot_file)).readlines()

            os.remove(os.path.join(self.get_working_directory(), spot_file))

            peaks = []

            for record in output[3:-2]:
                lst = record.split()
                x = float(lst[0])
                y = float(lst[1])
                i = float(lst[4]) / float(lst[5])
                x /= pixel[0]
                y /= pixel[1]

                if i < threshold:
                    continue

                # this is Mosflm right? Swap X & Y!!

                peaks.append((y, x, i))

            return peaks
Example #5
0
  def _setup_from_image(self, image):
    '''Configure myself from an image name.'''
    template, directory = image2template_directory(image)
    self._fp_matching_images = find_matching_images(template, directory)

    # trim this down to only allowed images...
    if self._fp_wedge:
      start, end = self._fp_wedge
      images = []
      for j in self._fp_matching_images:
        if j < start or j > end:
          continue
        images.append(j)
      self._fp_matching_images = images

    from xia2.Schema import load_imagesets
    imagesets = load_imagesets(
      template, directory,
      image_range=(self._fp_matching_images[0], self._fp_matching_images[-1]))
    assert len(imagesets) == 1, 'multiple imagesets match %s' % template
    imageset = imagesets[0]

    self._setup_from_imageset(imageset)
    return
Example #6
0
File: Sweep.py Project: hainm/xia2
        if scan is None: continue
        if imageset.get_scan().get_num_images() > max_images:
          best_sweep = imageset

      self._imageset = best_sweep

    return

if __name__ == '__main__':

  if len(sys.argv) < 2:
    image = os.path.join(os.environ['XIA2_ROOT'],
                         'Data', 'Test', 'Images', '12287_1_E1_001.img')
  else:
    image = sys.argv[1]

  template, directory = image2template_directory(image)

  sl = SweepFactory(template, directory)

  for s in sl:

    t = s.get_collect()
    print 'Data collection took %s seconds' % (t[1] - t[0])
    print 'For a total of %s seconds of exposure' % \
          (s.get_exposure_time() * \
           len(s.get_images()))
    print 'Images: %d to %d' % (min(s.get_images()), max(s.get_images()))
    print 'Template: %s' % s.get_template()
    print ''
Example #7
0
    def setup(self):
        """Set everything up..."""

        # check arguments are all ascii

        Debug.write("Start parsing command line: " + str(sys.argv))

        for token in sys.argv:
            try:
                token.encode("ascii")
            except UnicodeDecodeError:
                raise RuntimeError("non-ascii characters in input")

        self._argv = copy.deepcopy(sys.argv)

        replacements = {
            "-2d": "pipeline=2d",
            "-2di": "pipeline=2di",
            "-3d": "pipeline=3d",
            "-3di": "pipeline=3di",
            "-3dii": "pipeline=3dii",
            "-3dd": "pipeline=3dd",
            "-dials": "pipeline=dials",
            "-quick": "dials.fast_mode=true",
            "-failover": "failover=true",
            "-small_molecule": "small_molecule=true",
        }
        for k, v in replacements.iteritems():
            if k in self._argv:
                print(
                    "***\nCommand line option %s is deprecated.\nPlease use %s instead\n***"
                    % (k, v))
                self._argv[self._argv.index(k)] = v
        if "-atom" in self._argv:
            idx = self._argv.index("-atom")
            element = self._argv[idx + 1]
            self._argv[idx:idx + 2] = ["atom=%s" % element]
            print(
                "***\nCommand line option -atom %s is deprecated.\nPlease use atom=%s instead\n***"
                % (element, element))

        # first of all try to interpret arguments as phil parameters/files

        from xia2.Handlers.Phil import master_phil
        from libtbx.phil import command_line

        cmd_line = command_line.argument_interpreter(master_phil=master_phil)
        working_phil, self._argv = cmd_line.process_and_fetch(
            args=self._argv, custom_processor="collect_remaining")

        PhilIndex.merge_phil(working_phil)
        try:
            params = PhilIndex.get_python_object()
        except RuntimeError as e:
            raise Sorry(e)

        # sanity check / interpret Auto in input
        from libtbx import Auto

        if params.xia2.settings.input.atom is None:
            if params.xia2.settings.input.anomalous is Auto:
                PhilIndex.update("xia2.settings.input.anomalous=false")
        else:
            if params.xia2.settings.input.anomalous is False:
                raise Sorry(
                    "Setting anomalous=false and atom type inconsistent")
            params.xia2.settings.input.anomalous = True
            PhilIndex.update("xia2.settings.input.anomalous=true")

        if params.xia2.settings.resolution.keep_all_reflections is Auto:
            if (params.xia2.settings.small_molecule is True
                    and params.xia2.settings.resolution.d_min is None
                    and params.xia2.settings.resolution.d_max is None):
                PhilIndex.update(
                    "xia2.settings.resolution.keep_all_reflections=true")
            else:
                PhilIndex.update(
                    "xia2.settings.resolution.keep_all_reflections=false")

        if params.xia2.settings.small_molecule is True:
            Debug.write("Small molecule selected")
            if params.xia2.settings.symmetry.chirality is None:
                PhilIndex.update("xia2.settings.symmetry.chirality=nonchiral")
            params = PhilIndex.get_python_object()

        # pipeline options
        self._read_pipeline()

        for (parameter, value) in (
            ("project", params.xia2.settings.project),
            ("crystal", params.xia2.settings.crystal),
        ):
            validate_project_crystal_name(parameter, value)

        Debug.write("Project: %s" % params.xia2.settings.project)
        Debug.write("Crystal: %s" % params.xia2.settings.crystal)

        # FIXME add some consistency checks in here e.g. that there are
        # images assigned, there is a lattice assigned if cell constants
        # are given and so on

        params = PhilIndex.get_python_object()
        mp_params = params.xia2.settings.multiprocessing
        from xia2.Handlers.Environment import get_number_cpus

        if mp_params.mode == "parallel":
            if mp_params.type == "qsub":
                if which("qsub") is None:
                    raise Sorry("qsub not available")
            if mp_params.njob is Auto:
                mp_params.njob = get_number_cpus()
                if mp_params.nproc is Auto:
                    mp_params.nproc = 1
            elif mp_params.nproc is Auto:
                mp_params.nproc = get_number_cpus()
        elif mp_params.mode == "serial":
            if mp_params.type == "qsub":
                if which("qsub") is None:
                    raise Sorry("qsub not available")
            if mp_params.njob is Auto:
                mp_params.njob = 1
            if mp_params.nproc is Auto:
                mp_params.nproc = get_number_cpus()

        PhilIndex.update("xia2.settings.multiprocessing.njob=%d" %
                         mp_params.njob)
        PhilIndex.update("xia2.settings.multiprocessing.nproc=%d" %
                         mp_params.nproc)
        params = PhilIndex.get_python_object()
        mp_params = params.xia2.settings.multiprocessing

        if mp_params.nproc > 1 and os.name == "nt":
            raise Sorry("nproc > 1 is not supported on Windows.")  # #191

        if params.xia2.settings.indexer is not None:
            add_preference("indexer", params.xia2.settings.indexer)
        if params.xia2.settings.refiner is not None:
            add_preference("refiner", params.xia2.settings.refiner)
        if params.xia2.settings.integrater is not None:
            add_preference("integrater", params.xia2.settings.integrater)
        if params.xia2.settings.scaler is not None:
            add_preference("scaler", params.xia2.settings.scaler)

        if params.xia2.settings.multi_sweep_indexing is Auto:
            if (params.xia2.settings.small_molecule is True
                    and "dials" == params.xia2.settings.indexer):
                PhilIndex.update("xia2.settings.multi_sweep_indexing=True")
            else:
                PhilIndex.update("xia2.settings.multi_sweep_indexing=False")
        if (params.xia2.settings.multi_sweep_indexing is True
                and params.xia2.settings.multiprocessing.mode == "parallel"):
            Chatter.write(
                "Multi sweep indexing disabled:\nMSI is not available for parallel processing."
            )
            PhilIndex.update("xia2.settings.multi_sweep_indexing=False")

        input_json = params.xia2.settings.input.json
        if input_json is not None and len(input_json):
            for json_file in input_json:
                assert os.path.isfile(json_file)
                load_experiments(json_file)

        reference_geometry = params.xia2.settings.input.reference_geometry
        if reference_geometry is not None and len(reference_geometry) > 0:
            reference_geometries = "\n".join([
                "xia2.settings.input.reference_geometry=%s" %
                os.path.abspath(g)
                for g in params.xia2.settings.input.reference_geometry
            ])
            Debug.write(reference_geometries)
            PhilIndex.update(reference_geometries)
            Debug.write("xia2.settings.trust_beam_centre=true")
            PhilIndex.update("xia2.settings.trust_beam_centre=true")
            params = PhilIndex.get_python_object()

        params = PhilIndex.get_python_object()
        if params.xia2.settings.input.xinfo is not None:
            xinfo_file = os.path.abspath(params.xia2.settings.input.xinfo)
            PhilIndex.update("xia2.settings.input.xinfo=%s" % xinfo_file)
            params = PhilIndex.get_python_object()
            self.set_xinfo(xinfo_file)

            # issue #55 if not set ATOM in xinfo but anomalous=true or atom= set
            # on commandline, set here, should be idempotent

            if params.xia2.settings.input.anomalous is True:
                crystals = self._xinfo.get_crystals()
                for xname in crystals:
                    xtal = crystals[xname]
                    Debug.write("Setting anomalous for crystal %s" % xname)
                    xtal.set_anomalous(True)
        else:
            xinfo_file = "%s/automatic.xinfo" % os.path.abspath(os.curdir)
            PhilIndex.update("xia2.settings.input.xinfo=%s" % xinfo_file)
            params = PhilIndex.get_python_object()

        if params.dials.find_spots.phil_file is not None:
            PhilIndex.update(
                "dials.find_spots.phil_file=%s" %
                os.path.abspath(params.dials.find_spots.phil_file))
        if params.dials.index.phil_file is not None:
            PhilIndex.update("dials.index.phil_file=%s" %
                             os.path.abspath(params.dials.index.phil_file))
        if params.dials.refine.phil_file is not None:
            PhilIndex.update("dials.refine.phil_file=%s" %
                             os.path.abspath(params.dials.refine.phil_file))
        if params.dials.integrate.phil_file is not None:
            PhilIndex.update("dials.integrate.phil_file=%s" %
                             os.path.abspath(params.dials.integrate.phil_file))
        if params.xds.index.xparm is not None:
            Flags.set_xparm(params.xds.index.xparm)
        if params.xds.index.xparm_ub is not None:
            Flags.set_xparm_ub(params.xds.index.xparm_ub)

        if params.xia2.settings.scale.freer_file is not None:
            freer_file = os.path.abspath(params.xia2.settings.scale.freer_file)
            if not os.path.exists(freer_file):
                raise RuntimeError("%s does not exist" % freer_file)
            from xia2.Modules.FindFreeFlag import FindFreeFlag

            column = FindFreeFlag(freer_file)
            Debug.write("FreeR_flag column in %s found: %s" %
                        (freer_file, column))
            PhilIndex.update("xia2.settings.scale.freer_file=%s" % freer_file)

        if params.xia2.settings.scale.reference_reflection_file is not None:
            reference_reflection_file = os.path.abspath(
                params.xia2.settings.scale.reference_reflection_file)
            if not os.path.exists(reference_reflection_file):
                raise RuntimeError("%s does not exist" %
                                   reference_reflection_file)
            PhilIndex.update(
                "xia2.settings.scale.reference_reflection_file=%s" %
                reference_reflection_file)

        params = PhilIndex.get_python_object()

        datasets = unroll_datasets(PhilIndex.params.xia2.settings.input.image)

        for dataset in datasets:

            start_end = None

            # here we only care about ':' which are later than C:\
            if ":" in dataset[3:]:
                tokens = dataset.split(":")
                # cope with windows drives i.e. C:\data\blah\thing_0001.cbf:1:100
                if len(tokens[0]) == 1:
                    tokens = ["%s:%s" % (tokens[0], tokens[1])] + tokens[2:]
                if len(tokens) != 3:
                    raise RuntimeError("/path/to/image_0001.cbf:start:end")

                dataset = tokens[0]
                start_end = int(tokens[1]), int(tokens[2])

            from xia2.Applications.xia2setup import is_hd5f_name

            if os.path.exists(os.path.abspath(dataset)):
                dataset = os.path.abspath(dataset)
            else:
                directories = [os.getcwd()] + self._argv[1:]
                found = False
                for d in directories:
                    if os.path.exists(os.path.join(d, dataset)):
                        dataset = os.path.join(d, dataset)
                        found = True
                        break
                if not found:
                    raise Sorry("Could not find %s in %s" %
                                (dataset, " ".join(directories)))

            if is_hd5f_name(dataset):
                self._hdf5_master_files.append(dataset)
                if start_end:
                    Debug.write("Image range: %d %d" % start_end)
                    if dataset not in self._default_start_end:
                        self._default_start_end[dataset] = []
                    self._default_start_end[dataset].append(start_end)
                else:
                    Debug.write("No image range specified")

            else:
                template, directory = image2template_directory(
                    os.path.abspath(dataset))

                self._default_template.append(os.path.join(
                    directory, template))
                self._default_directory.append(directory)

                Debug.write("Interpreted from image %s:" % dataset)
                Debug.write("Template %s" % template)
                Debug.write("Directory %s" % directory)

                if start_end:
                    Debug.write("Image range: %d %d" % start_end)
                    key = os.path.join(directory, template)
                    if key not in self._default_start_end:
                        self._default_start_end[key] = []
                    self._default_start_end[key].append(start_end)
                else:
                    Debug.write("No image range specified")

        # finally, check that all arguments were read and raise an exception
        # if any of them were nonsense.

        with open("xia2-working.phil", "wb") as f:
            f.write(PhilIndex.working_phil.as_str())
            f.write(
                os.linesep
            )  # temporarily required for https://github.com/dials/dials/issues/522
        with open("xia2-diff.phil", "wb") as f:
            f.write(PhilIndex.get_diff().as_str())
            f.write(
                os.linesep
            )  # temporarily required for https://github.com/dials/dials/issues/522

        Debug.write("\nDifference PHIL:")
        Debug.write(PhilIndex.get_diff().as_str(), strip=False)

        Debug.write("Working PHIL:")
        Debug.write(PhilIndex.working_phil.as_str(), strip=False)

        nonsense = "Unknown command-line options:"
        was_nonsense = False

        for j, argv in enumerate(self._argv):
            if j == 0:
                continue
            if argv[0] != "-" and "=" not in argv:
                continue
            if j not in self._understood:
                nonsense += " %s" % argv
                was_nonsense = True

        if was_nonsense:
            raise RuntimeError(nonsense)
Example #8
0
                if imageset.get_scan().get_num_images() > max_images:
                    best_sweep = imageset

            self._imageset = best_sweep

        return


if __name__ == '__main__':

    if len(sys.argv) < 2:
        image = os.path.join(os.environ['XIA2_ROOT'], 'Data', 'Test', 'Images',
                             '12287_1_E1_001.img')
    else:
        image = sys.argv[1]

    template, directory = image2template_directory(image)

    sl = SweepFactory(template, directory)

    for s in sl:

        t = s.get_collect()
        print 'Data collection took %s seconds' % (t[1] - t[0])
        print 'For a total of %s seconds of exposure' % \
              (s.get_exposure_time() * \
               len(s.get_images()))
        print 'Images: %d to %d' % (min(s.get_images()), max(s.get_images()))
        print 'Template: %s' % s.get_template()
        print ''
Example #9
0
File: XSweep.py Project: xia2/xia2
  def __init__(self, name,
               wavelength,
               sample,
               directory = None,
               image = None,
               beam = None,
               reversephi = False,
               distance = None,
               gain = 0.0,
               dmin = 0.0,
               dmax = 0.0,
               polarization = 0.0,
               frames_to_process = None,
               user_lattice = None,
               user_cell = None,
               epoch = 0,
               ice = False,
               excluded_regions = None):
    '''Create a new sweep named name, belonging to XWavelength object
    wavelength, representing the images in directory starting with image,
    with beam centre optionally defined.'''
    if excluded_regions is None:
      excluded_regions = []

    # + check the wavelength is an XWavelength object
    #   raise an exception if not... or not...

    if not wavelength.__class__.__name__ == 'XWavelength':
      pass

    # FIXME bug 2221 if DIRECTORY starts with ~/ or ~graeme (say) need to
    # interpret this properly - e.g. map it to a full PATH.

    directory = expand_path(directory)

    self._name = name
    self._wavelength = wavelength
    self._sample = sample
    self._directory = directory
    self._image = image
    self._reversephi = reversephi
    self._epoch = epoch
    self._user_lattice = user_lattice
    self._user_cell = user_cell
    self._header = { }
    self._resolution_high = dmin
    self._resolution_low = dmax
    self._ice = ice
    self._excluded_regions = excluded_regions
    self._imageset = None

    # FIXME in here also need to be able to accumulate the total
    # dose from all experimental measurements (complex) and provide
    # a _epoch_to_dose dictionary or some such... may be fiddly as
    # this will need to parse across multiple templates. c/f Bug # 2798

    self._epoch_to_image = { }
    self._image_to_epoch = { }

    # to allow first, last image for processing to be
    # set... c/f integrater interface
    self._frames_to_process = frames_to_process

    # + derive template, list of images

    params = PhilIndex.get_python_object()
    if directory and image:
      self._template, self._directory = \
                      image2template_directory(os.path.join(directory,
                                                            image))

      from xia2.Schema import load_imagesets
      imagesets = load_imagesets(
        self._template, self._directory, image_range=self._frames_to_process,
        reversephi=(params.xia2.settings.input.reverse_phi or self._reversephi))

      assert len(imagesets) == 1, "one imageset expected, %d found" % \
          len(imagesets)
      self._imageset = copy.deepcopy(imagesets[0])
      start, end = self._imageset.get_array_range()
      self._images = list(range(start+1, end+1))

      # FIXME in here check that (1) the list of images is continuous
      # and (2) that all of the images are readable. This should also
      # take into account frames_to_process if set.

      if self._frames_to_process is None:
        self._frames_to_process = min(self._images), max(self._images)

      start, end = self._frames_to_process

      error = False

      if params.general.check_image_files_readable:
        for j in range(start, end + 1):
          image_name = self.get_imageset().get_path(j-start)
          if not j in self._images:
            Debug.write('image %s missing' %image_name)
            error = True
            continue
          if not os.access(image_name, os.R_OK):
            Debug.write('image %s unreadable' %image_name)
            error = True
            continue

        if error:
          raise RuntimeError, 'problem with sweep %s' % self._name

      # + read the image header information into here?
      #   or don't I need it? it would be useful for checking
      #   against wavelength.getWavelength() I guess to make
      #   sure that the plumbing is all sound.

      # check that they match by closer than 0.0001A, if wavelength
      # is not None

      beam_ = self._imageset.get_beam()
      scan = self._imageset.get_scan()
      if wavelength is not None:

        # FIXME 29/NOV/06 if the wavelength wavelength value
        # is 0.0 then first set it to the header value - note
        # that this assumes that the header value is correct
        # (a reasonable assumption)

        if wavelength.get_wavelength() == 0.0:
          wavelength.set_wavelength(beam_.get_wavelength())

        # FIXME 08/DEC/06 in here need to allow for the fact
        # that the wavelength in the image header could be wrong and
        # in fact it should be replaced with the input value -
        # through the user will need to be warned of this and
        # also everything using the FrameProcessor interface
        # will also have to respect this!

        if math.fabs(beam_.get_wavelength() -
                     wavelength.get_wavelength()) > 0.0001:
          # format = 'wavelength for sweep %s does not ' + \
          # 'match wavelength %s'
          # raise RuntimeError, format  % \
          # (name, wavelength.get_name())

          format = 'Header wavelength for sweep %s different' + \
                   ' to assigned value (%4.2f vs. %4.2f)'

          Chatter.write(format % (name, beam_.get_wavelength(),
                                  wavelength.get_wavelength()))


      # also in here look at the image headers to see if we can
      # construct a mapping between exposure epoch and image ...

      images = []

      if self._frames_to_process:
        start, end = self._frames_to_process
        for j in self._images:
          if j >= start and j <= end:
            images.append(j)
      else:
        images = self._images

      for j in images:
        epoch = scan.get_image_epoch(j)
        if epoch == 0.0:
          epoch = float(os.stat(self._imageset.get_path(j-images[0])).st_mtime)
        self._epoch_to_image[epoch] = j
        self._image_to_epoch[j] = epoch

      epochs = self._epoch_to_image.keys()

      Debug.write('Exposure epoch for sweep %s: %d %d' % \
                  (self._template, min(epochs), max(epochs)))

    self._input_imageset = copy.deepcopy(self._imageset)

    # + get the lattice - can this be a pointer, so that when
    #   this object updates lattice it is globally-for-this-crystal
    #   updated? The lattice included directly in here includes an
    #   exact unit cell for data reduction, the crystal lattice
    #   contains an approximate unit cell which should be
    #   from the unit cells from all sweeps contained in the
    #   XCrystal. FIXME should I be using a LatticeInfo object
    #   in here? See what the Indexer interface produces. ALT:
    #   just provide an Indexer implementation "hook".
    #   See Headnote 001 above. See also _get_indexer,
    #   _get_integrater below.

    self._indexer = None
    self._refiner = None
    self._integrater = None

    # I don't need this - it is equivalent to self.getWavelength(
    # ).getCrystal().getLattice()
    # self._crystal_lattice = None

    # this means that this module will have to present largely the
    # same interface as Indexer and Integrater so that the calls
    # can be appropriately forwarded.

    # finally configure the beam if set

    if beam is not None:
      from dxtbx.model.detector_helpers import set_mosflm_beam_centre
      try:
        set_mosflm_beam_centre(self.get_imageset().get_detector(),
                               self.get_imageset().get_beam(),
                               beam)
      except AssertionError, e:
        Debug.write('Error setting mosflm beam centre: %s' % e)
Example #10
0
    def setup(self):
        '''Set everything up...'''

        # check arguments are all ascii

        Debug.write('Start parsing command line: ' + str(sys.argv))

        for token in sys.argv:
            try:
                token.encode('ascii')
            except UnicodeDecodeError:
                raise RuntimeError('non-ascii characters in input')

        self._argv = copy.deepcopy(sys.argv)

        replacements = {
            '-2d': 'pipeline=2d',
            '-2di': 'pipeline=2di',
            '-3d': 'pipeline=3d',
            '-3di': 'pipeline=3di',
            '-3dii': 'pipeline=3dii',
            '-3dd': 'pipeline=3dd',
            '-dials': 'pipeline=dials',
            '-quick': 'dials.fast_mode=true',
            '-failover': 'failover=true',
            '-small_molecule': 'small_molecule=true'
        }
        for k, v in replacements.iteritems():
            if k in self._argv:
                print "***\nCommand line option %s is deprecated.\nPlease use %s instead\n***" % (
                    k, v)
                self._argv[self._argv.index(k)] = v
        if '-atom' in self._argv:
            idx = self._argv.index('-atom')
            element = self._argv[idx + 1]
            self._argv[idx:idx + 2] = ['atom=%s' % element]
            print "***\nCommand line option -atom %s is deprecated.\nPlease use atom=%s instead\n***" % (
                element, element)

        # first of all try to interpret arguments as phil parameters/files

        from xia2.Handlers.Phil import master_phil
        from libtbx.phil import command_line
        cmd_line = command_line.argument_interpreter(master_phil=master_phil)
        working_phil, self._argv = cmd_line.process_and_fetch(
            args=self._argv, custom_processor="collect_remaining")

        PhilIndex.merge_phil(working_phil)
        try:
            params = PhilIndex.get_python_object()
        except RuntimeError as e:
            raise Sorry(e)

        # sanity check / interpret Auto in input
        from libtbx import Auto

        if params.xia2.settings.input.atom is None:
            if params.xia2.settings.input.anomalous is Auto:
                PhilIndex.update("xia2.settings.input.anomalous=false")
        else:
            if params.xia2.settings.input.anomalous == False:
                raise Sorry(
                    'Setting anomalous=false and atom type inconsistent')
            params.xia2.settings.input.anomalous = True
            PhilIndex.update("xia2.settings.input.anomalous=true")

        if params.xia2.settings.resolution.keep_all_reflections is Auto:
            if params.xia2.settings.small_molecule == True and \
               params.xia2.settings.resolution.d_min is None and \
               params.xia2.settings.resolution.d_max is None:
                PhilIndex.update(
                    "xia2.settings.resolution.keep_all_reflections=true")
            else:
                PhilIndex.update(
                    "xia2.settings.resolution.keep_all_reflections=false")

        if params.xia2.settings.small_molecule == True:
            Debug.write('Small molecule selected')
            if params.ccp4.pointless.chirality is None:
                PhilIndex.update("ccp4.pointless.chirality=nonchiral")
            params = PhilIndex.get_python_object()

        # pipeline options
        self._read_pipeline()

        Debug.write('Project: %s' % params.xia2.settings.project)
        Debug.write('Crystal: %s' % params.xia2.settings.crystal)

        # FIXME add some consistency checks in here e.g. that there are
        # images assigned, there is a lattice assigned if cell constants
        # are given and so on

        params = PhilIndex.get_python_object()
        mp_params = params.xia2.settings.multiprocessing
        from xia2.Handlers.Environment import get_number_cpus
        if mp_params.mode == 'parallel':
            if mp_params.type == 'qsub':
                if which('qsub') is None:
                    raise Sorry('qsub not available')
            if mp_params.njob is Auto:
                mp_params.njob = get_number_cpus()
                if mp_params.nproc is Auto:
                    mp_params.nproc = 1
            elif mp_params.nproc is Auto:
                mp_params.nproc = get_number_cpus()
        elif mp_params.mode == 'serial':
            if mp_params.type == 'qsub':
                if which('qsub') is None:
                    raise Sorry('qsub not available')
            if mp_params.njob is Auto:
                mp_params.njob = 1
            if mp_params.nproc is Auto:
                mp_params.nproc = get_number_cpus()

        PhilIndex.update("xia2.settings.multiprocessing.njob=%d" %
                         mp_params.njob)
        PhilIndex.update("xia2.settings.multiprocessing.nproc=%d" %
                         mp_params.nproc)
        params = PhilIndex.get_python_object()
        mp_params = params.xia2.settings.multiprocessing

        if params.xia2.settings.indexer is not None:
            add_preference("indexer", params.xia2.settings.indexer)
        if params.xia2.settings.refiner is not None:
            add_preference("refiner", params.xia2.settings.refiner)
        if params.xia2.settings.integrater is not None:
            add_preference("integrater", params.xia2.settings.integrater)
        if params.xia2.settings.scaler is not None:
            add_preference("scaler", params.xia2.settings.scaler)

        if params.xia2.settings.multi_sweep_indexing is Auto:
            if params.xia2.settings.small_molecule == True and 'dials' == params.xia2.settings.indexer:
                PhilIndex.update("xia2.settings.multi_sweep_indexing=True")
            else:
                PhilIndex.update("xia2.settings.multi_sweep_indexing=False")
        if params.xia2.settings.multi_sweep_indexing == True and \
           params.xia2.settings.multiprocessing.mode == 'parallel':
            Chatter.write(
                'Multi sweep indexing disabled:\nMSI is not available for parallel processing.'
            )
            PhilIndex.update("xia2.settings.multi_sweep_indexing=False")

        input_json = params.xia2.settings.input.json
        if (input_json is not None and len(input_json)):
            for json_file in input_json:
                assert os.path.isfile(json_file)
                load_datablock(json_file)

        reference_geometry = params.xia2.settings.input.reference_geometry
        if reference_geometry is not None and len(reference_geometry) > 0:
            reference_geometries = "\n".join([
                "xia2.settings.input.reference_geometry=%s" %
                os.path.abspath(g)
                for g in params.xia2.settings.input.reference_geometry
            ])
            Debug.write(reference_geometries)
            PhilIndex.update(reference_geometries)
            Debug.write("xia2.settings.trust_beam_centre=true")
            PhilIndex.update("xia2.settings.trust_beam_centre=true")
            params = PhilIndex.get_python_object()

        params = PhilIndex.get_python_object()
        if params.xia2.settings.input.xinfo is not None:
            xinfo_file = os.path.abspath(params.xia2.settings.input.xinfo)
            PhilIndex.update("xia2.settings.input.xinfo=%s" % xinfo_file)
            params = PhilIndex.get_python_object()
            self.set_xinfo(xinfo_file)

            # issue #55 if not set ATOM in xinfo but anomalous=true or atom= set
            # on commandline, set here, should be idempotent

            if params.xia2.settings.input.anomalous is True:
                crystals = self._xinfo.get_crystals()
                for xname in crystals:
                    xtal = crystals[xname]
                    Debug.write("Setting anomalous for crystal %s" % xname)
                    xtal.set_anomalous(True)
        else:
            xinfo_file = '%s/automatic.xinfo' % os.path.abspath(os.curdir)
            PhilIndex.update("xia2.settings.input.xinfo=%s" % xinfo_file)
            params = PhilIndex.get_python_object()

        if params.dials.find_spots.phil_file is not None:
            PhilIndex.update(
                "dials.find_spots.phil_file=%s" %
                os.path.abspath(params.dials.find_spots.phil_file))
        if params.dials.index.phil_file is not None:
            PhilIndex.update("dials.index.phil_file=%s" %
                             os.path.abspath(params.dials.index.phil_file))
        if params.dials.refine.phil_file is not None:
            PhilIndex.update("dials.refine.phil_file=%s" %
                             os.path.abspath(params.dials.refine.phil_file))
        if params.dials.integrate.phil_file is not None:
            PhilIndex.update("dials.integrate.phil_file=%s" %
                             os.path.abspath(params.dials.integrate.phil_file))
        if params.xds.index.xparm is not None:
            Flags.set_xparm(params.xds.index.xparm)
        if params.xds.index.xparm_ub is not None:
            Flags.set_xparm_ub(params.xds.index.xparm_ub)

        if params.xia2.settings.scale.freer_file is not None:
            freer_file = os.path.abspath(params.xia2.settings.scale.freer_file)
            if not os.path.exists(freer_file):
                raise RuntimeError('%s does not exist' % freer_file)
            from xia2.Modules.FindFreeFlag import FindFreeFlag
            column = FindFreeFlag(freer_file)
            Debug.write('FreeR_flag column in %s found: %s' % \
                        (freer_file, column))
            PhilIndex.update("xia2.settings.scale.freer_file=%s" % freer_file)

        if params.xia2.settings.scale.reference_reflection_file is not None:
            reference_reflection_file = os.path.abspath(
                params.xia2.settings.scale.reference_reflection_file)
            if not os.path.exists(reference_reflection_file):
                raise RuntimeError('%s does not exist' %
                                   reference_reflection_file)
            PhilIndex.update(
                "xia2.settings.scale.reference_reflection_file=%s" %
                reference_reflection_file)

        params = PhilIndex.get_python_object()

        datasets = unroll_datasets(PhilIndex.params.xia2.settings.input.image)

        for dataset in datasets:

            start_end = None

            if ':' in dataset:
                tokens = dataset.split(':')
                # cope with windows drives i.e. C:\data\blah\thing_0001.cbf:1:100
                if len(tokens[0]) == 1:
                    tokens = ['%s:%s' % (tokens[0], tokens[1])] + tokens[2:]
                if len(tokens) != 3:
                    raise RuntimeError('/path/to/image_0001.cbf:start:end')

                dataset = tokens[0]
                start_end = int(tokens[1]), int(tokens[2])

            from xia2.Applications.xia2setup import is_hd5f_name
            if os.path.exists(os.path.abspath(dataset)):
                dataset = os.path.abspath(dataset)
            else:
                directories = [os.getcwd()] + self._argv[1:]
                found = False
                for d in directories:
                    if os.path.exists(os.path.join(d, dataset)):
                        dataset = os.path.join(d, dataset)
                        found = True
                        break
                if not found:
                    raise Sorry('Cound not find %s in %s' % \
                                (dataset, ' '.join(directories)))

            if is_hd5f_name(dataset):
                self._hdf5_master_files.append(dataset)
                if start_end:
                    Debug.write('Image range: %d %d' % start_end)
                    if not dataset in self._default_start_end:
                        self._default_start_end[dataset] = []
                    self._default_start_end[dataset].append(start_end)
                else:
                    Debug.write('No image range specified')

            else:
                template, directory = image2template_directory(
                    os.path.abspath(dataset))

                self._default_template.append(os.path.join(
                    directory, template))
                self._default_directory.append(directory)

                Debug.write('Interpreted from image %s:' % dataset)
                Debug.write('Template %s' % template)
                Debug.write('Directory %s' % directory)

                if start_end:
                    Debug.write('Image range: %d %d' % start_end)
                    key = os.path.join(directory, template)
                    if not key in self._default_start_end:
                        self._default_start_end[key] = []
                    self._default_start_end[key].append(start_end)
                else:
                    Debug.write('No image range specified')

        # finally, check that all arguments were read and raise an exception
        # if any of them were nonsense.

        with open('xia2-working.phil', 'wb') as f:
            print >> f, PhilIndex.working_phil.as_str()
        with open('xia2-diff.phil', 'wb') as f:
            print >> f, PhilIndex.get_diff().as_str()

        Debug.write('\nDifference PHIL:')
        Debug.write(PhilIndex.get_diff().as_str(), strip=False)

        Debug.write('Working PHIL:')
        Debug.write(PhilIndex.working_phil.as_str(), strip=False)

        nonsense = 'Unknown command-line options:'
        was_nonsense = False

        for j, argv in enumerate(self._argv):
            if j == 0:
                continue
            if argv[0] != '-' and '=' not in argv:
                continue
            if not j in self._understood:
                nonsense += ' %s' % argv
                was_nonsense = True

        if was_nonsense:
            raise RuntimeError(nonsense)
Example #11
0
def exercise_mosflm_index():
  if not have_dials_regression:
    print "Skipping exercise_mosflm_index(): dials_regression not configured"
    return


  xia2_demo_data = os.path.join(dials_regression, "xia2_demo_data")
  template = os.path.join(xia2_demo_data, "insulin_1_%03i.img")

  from xia2.Wrappers.Mosflm.MosflmIndex import MosflmIndex

  # exercise basic indexing from two images
  cwd = os.path.abspath(os.curdir)
  tmp_dir = open_tmp_directory()
  os.chdir(tmp_dir)

  indexer = MosflmIndex()
  indexer.set_images((1,45))

  from xia2.Experts.FindImages import image2template_directory
  templ, directory = image2template_directory(template %1)

  indexer.set_directory(directory)
  indexer.set_template(templ)
  indexer.run()
  output = ''.join(indexer.get_all_output())
  print output
  assert approx_equal(indexer.get_refined_beam_centre(), (94.33, 94.58))
  assert approx_equal(indexer.get_refined_unit_cell(),
                      (78.655, 78.655, 78.655, 90.0, 90.0, 90.0), 1e-3)
  assert approx_equal(indexer.get_refined_distance(), 160.0)
  assert approx_equal(indexer.get_resolution_estimate(), 2.12)
  assert approx_equal(indexer.get_separation(), [0.57, 0.57])
  assert approx_equal(indexer.get_raster(), [17, 17, 10, 5, 5])
  assert approx_equal(indexer.get_mosaic_spreads(), [0.4, 0.4])
  assert indexer.get_lattice() == 'cI'

  # now exercise indexing off multiple images and test more settings
  os.chdir(cwd)
  tmp_dir = open_tmp_directory()
  os.chdir(tmp_dir)

  indexer = MosflmIndex()
  indexer.set_images((5,15,25,35,45))
  indexer.set_directory(directory)
  indexer.set_template(templ)
  indexer.set_unit_cell((78,78,78,90,90,90))
  indexer.set_distance(159)
  indexer.set_space_group_number(197)
  indexer.run()
  output = ''.join(indexer.get_all_output())
  print output
  assert approx_equal(indexer.get_refined_beam_centre(), (94.33, 94.57))
  assert approx_equal(indexer.get_refined_unit_cell(),
                      (78.2082, 78.2082, 78.2082, 90.0, 90.0, 90.0))
  assert approx_equal(indexer.get_refined_distance(), 159.0)
  assert approx_equal(indexer.get_resolution_estimate(), 2.12)
  assert approx_equal(indexer.get_separation(), [0.48, 0.57])
  assert approx_equal(indexer.get_raster(), [15, 17, 9, 5, 5])
  assert approx_equal(
    indexer.get_mosaic_spreads(), [0.5, 0.35, 0.45, 0.65, 0.4], eps=1e-1)
  assert indexer.get_lattice() == 'cI'
Example #12
0
def exercise_mosflm_refine_cell():
  if not have_dials_regression:
    print "Skipping exercise_mosflm_refine_cell(): dials_regression not configured"
    return


  xia2_demo_data = os.path.join(dials_regression, "xia2_demo_data")
  template = os.path.join(xia2_demo_data, "insulin_1_%03i.img")

  from xia2.Wrappers.Mosflm.MosflmIndex import MosflmIndex
  from xia2.Wrappers.Mosflm.MosflmRefineCell import MosflmRefineCell

  # exercise basic indexing from two images
  cwd = os.path.abspath(os.curdir)
  tmp_dir = open_tmp_directory()
  os.chdir(tmp_dir)

  from xia2.Experts.FindImages import image2template_directory
  templ, directory = image2template_directory(template %1)

  indexer = MosflmIndex()
  indexer.set_images((1,45))
  indexer.set_directory(directory)
  indexer.set_template(templ)
  indexer.run()

  refiner = MosflmRefineCell()
  refiner.set_images(((1,3),(21,23), (43,45)))
  refiner.set_input_mat_file("xiaindex.mat")
  refiner.set_output_mat_file("xiarefine.mat")
  refiner.set_directory(directory)
  refiner.set_template(templ)
  refiner.set_beam_centre(indexer.get_refined_beam_centre())
  refiner.set_mosaic(
    sum(indexer.get_mosaic_spreads())/len(indexer.get_mosaic_spreads()))
  refiner.run()
  output = ''.join(refiner.get_all_output())
  print output

  background_residual = refiner.get_background_residual()
  rms_values = refiner.get_rms_values()

  ref_residual = {
    1: {1: 0.1, 2: 0.1, 3: 0.1, 43: 0.1, 44: 0.2, 45: 0.1, 21: 0.1, 22: 0.1, 23: 0.1},
    2: {1: 0.1, 2: 0.1, 3: 0.1, 43: 0.1, 44: 0.2, 45: 0.1, 21: 0.1, 22: 0.1, 23: 0.1},
    3: {1: 0.1, 2: 0.1, 3: 0.1, 43: 0.1, 44: 0.2, 45: 0.1, 21: 0.1, 22: 0.1, 23: 0.1}
  }

  for cycle in background_residual:
    for frame in background_residual[cycle]:
      assert abs(background_residual[cycle][frame] -
                 ref_residual[cycle][frame]) <= 0.1, (cycle, frame)

  ref_values = {
    1: [0.027, 0.029, 0.027, 0.025, 0.027, 0.025, 0.024, 0.022, 0.025],
    2: [0.02, 0.021, 0.023, 0.021, 0.02, 0.017, 0.018, 0.019, 0.022],
    3: [0.02, 0.021, 0.025, 0.022, 0.021, 0.019, 0.018, 0.019, 0.021]
  }

  for cycle in rms_values:
    for frame in range(len(rms_values[cycle])):
      assert abs(rms_values[cycle][frame] - ref_values[cycle][frame]) <= 0.05
Example #13
0
def exercise_mosflm_integrate():
  if not have_dials_regression:
    print "Skipping exercise_mosflm_integrate(): dials_regression not configured"
    return


  xia2_demo_data = os.path.join(dials_regression, "xia2_demo_data")
  template = os.path.join(xia2_demo_data, "insulin_1_%03i.img")

  from xia2.Wrappers.Mosflm.MosflmIndex import MosflmIndex
  from xia2.Wrappers.Mosflm.MosflmRefineCell import MosflmRefineCell
  from xia2.Wrappers.Mosflm.MosflmIntegrate import MosflmIntegrate

  # exercise basic indexing from two images
  cwd = os.path.abspath(os.curdir)
  tmp_dir = open_tmp_directory()
  os.chdir(tmp_dir)

  from xia2.Experts.FindImages import image2template_directory
  templ, directory = image2template_directory(template %1)

  indexer = MosflmIndex()
  indexer.set_images((1,45))
  indexer.set_directory(directory)
  indexer.set_template(templ)
  indexer.run()

  refiner = MosflmRefineCell()
  refiner.set_images(((1,3),(21,23), (43,45)))
  refiner.set_input_mat_file("xiaindex.mat")
  refiner.set_output_mat_file("xiarefine.mat")
  refiner.set_directory(directory)
  refiner.set_template(templ)
  refiner.set_beam_centre(indexer.get_refined_beam_centre())
  refiner.set_mosaic(
    sum(indexer.get_mosaic_spreads())/len(indexer.get_mosaic_spreads()))
  refiner.run()
  #output = ''.join(refiner.get_all_output())
  #print output

  integrater = MosflmIntegrate()
  integrater.set_image_range((1,45))
  integrater.set_input_mat_file("xiaindex.mat")
  #integrater.set_output_mat_file("xiarefine.mat")
  integrater.set_directory(directory)
  integrater.set_template(templ)
  integrater.set_beam_centre(
    tuple(float(x) for x in refiner.get_refined_beam_centre()))
  integrater.set_distance(refiner.get_refined_distance())
  integrater.set_mosaic(refiner.get_refined_mosaic())
  integrater.set_space_group_number(197)
  integrater.set_unit_cell(refiner.get_refined_unit_cell())
  integrater.run()
  hklout = integrater.get_hklout()
  assert os.path.exists(hklout)
  from iotbx.reflection_file_reader import any_reflection_file
  miller_arrays = any_reflection_file(hklout).as_miller_arrays(
    merge_equivalents=False)
  for ma in miller_arrays:
    assert ma.size() == 81011, ma.size()
  assert len(miller_arrays) == 13, len(miller_arrays)
  assert not integrater.get_bgsig_too_large()
  assert not integrater.get_getprof_error()
  assert integrater.get_batches_out() == (1, 45)
  assert integrater.get_mosaic_spreads() == [
    0.43, 0.42, 0.42, 0.41, 0.41, 0.41, 0.42, 0.42, 0.42, 0.42, 0.42, 0.42,
    0.41, 0.41, 0.41, 0.41, 0.41, 0.41, 0.41, 0.41, 0.4, 0.4, 0.4, 0.4, 0.4,
    0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4,
    0.4, 0.39, 0.39, 0.39, 0.39, 0.39]
  assert integrater.get_nref() == 81011
  assert len(integrater.get_postref_result()) == 45
  assert integrater.get_postref_result()[1] == {
    'ovrl': 0.0, 'full': 507.0, 'dist': 158.6, 'ccx': -0.01, 'yscale': 1.0,
    'sdrat': 7.5, 'tilt': 25.0, 'rsym': 0.027, 'bad': 0.0, 'i/sigi': 18.1,
    'i/sigi_out': 1.6, 'twist': 13.0, 'resid': 0.021, 'wresid': 1.1,
    'part': 1309.0, 'nsym': 18.0, 'neg': 158.0, 'ccy': -0.01, 'ccom': -0.01,
    'toff': 0.0, 'roff': 0.0}
  assert integrater.get_residuals() == [
    1.1, 0.9, 1.0, 1.0, 0.8, 0.9, 1.0, 0.8, 0.9, 0.9, 0.9, 0.9, 1.0, 1.0, 1.0,
    0.9, 0.9, 0.9, 0.9, 0.8, 1.0, 0.9, 0.8, 0.9, 1.0, 0.8, 1.0, 0.9, 0.8, 0.8,
    0.9, 0.9, 0.9, 0.9, 0.9, 1.0, 0.8, 0.9, 1.0, 0.7, 0.8, 0.9, 0.8, 0.9, 1.0]
  assert integrater.get_spot_status() \
         == 'ooooooooooooooooooooooooooooooooooooooooooooo'
def get_template_and_directory(dials_data):
    xia2_demo_data = dials_data("insulin")
    template = xia2_demo_data.join("insulin_1_%03i.img").strpath
    with mock.patch.object(sys, "argv", []):
        return image2template_directory(template % 1)
Example #15
0
def get_template_and_directory(xia2_regression_build):
    xia2_demo_data = os.path.join(xia2_regression_build, "test_data",
                                  "insulin")
    template = os.path.join(xia2_demo_data, "insulin_1_%03i.img")
    with mock.patch.object(sys, 'argv', []):
        return image2template_directory(template % 1)
Example #16
0
    def __init__(
        self,
        name,
        wavelength,
        sample,
        directory=None,
        image=None,
        beam=None,
        reversephi=False,
        distance=None,
        gain=0.0,
        dmin=0.0,
        dmax=0.0,
        polarization=0.0,
        frames_to_process=None,
        user_lattice=None,
        user_cell=None,
        epoch=0,
        ice=False,
        excluded_regions=None,
    ):
        """Create a new sweep named name, belonging to XWavelength object
        wavelength, representing the images in directory starting with image,
        with beam centre optionally defined."""
        if excluded_regions is None:
            excluded_regions = []

        # FIXME bug 2221 if DIRECTORY starts with ~/ or ~graeme (say) need to
        # interpret this properly - e.g. map it to a full PATH.

        directory = expand_path(directory)

        self._name = name
        self._wavelength = wavelength
        self.sample = sample
        self._directory = directory
        self._image = image
        self._reversephi = reversephi
        self._epoch = epoch
        self._user_lattice = user_lattice
        self._user_cell = user_cell
        self._header = {}
        self._resolution_high = dmin
        self._resolution_low = dmax
        self._ice = ice
        self._excluded_regions = excluded_regions
        self._imageset = None

        # FIXME in here also need to be able to accumulate the total
        # dose from all experimental measurements (complex) and provide
        # a _epoch_to_dose dictionary or some such... may be fiddly as
        # this will need to parse across multiple templates. c/f Bug # 2798

        self._epoch_to_image = {}
        self._image_to_epoch = {}

        # to allow first, last image for processing to be
        # set... c/f integrater interface
        self._frames_to_process = frames_to_process

        # + derive template, list of images

        params = PhilIndex.get_python_object()
        if directory and image:
            self._template, self._directory = image2template_directory(
                os.path.join(directory, image))

            from xia2.Schema import load_imagesets

            imagesets = load_imagesets(
                self._template,
                self._directory,
                image_range=self._frames_to_process,
                reversephi=(params.xia2.settings.input.reverse_phi
                            or self._reversephi),
            )

            assert len(
                imagesets
            ) == 1, "one imageset expected, %d found" % len(imagesets)
            self._imageset = copy.deepcopy(imagesets[0])
            start, end = self._imageset.get_array_range()
            self._images = list(range(start + 1, end + 1))

            # FIXME in here check that (1) the list of images is continuous
            # and (2) that all of the images are readable. This should also
            # take into account frames_to_process if set.

            if self._frames_to_process is None:
                self._frames_to_process = min(self._images), max(self._images)

            start, end = self._frames_to_process

            error = False

            if params.general.check_image_files_readable:
                for j in range(start, end + 1):
                    if j not in self._images:
                        logger.debug("image %i missing for %s" %
                                     (j, self.get_imageset().get_template()))
                        error = True
                        continue
                    image_name = self.get_imageset().get_path(j - start)
                    if not os.access(image_name, os.R_OK):
                        logger.debug("image %s unreadable" % image_name)
                        error = True
                        continue

                if error:
                    raise RuntimeError("problem with sweep %s" % self._name)

            beam_ = self._imageset.get_beam()
            scan = self._imageset.get_scan()
            if wavelength is not None:

                # If the wavelength value is 0.0 then first set it to the header
                # value - note that this assumes that the header value is correct
                # (a reasonable assumption)
                if wavelength.get_wavelength() == 0.0:
                    wavelength.set_wavelength(beam_.get_wavelength())

                # FIXME 08/DEC/06 in here need to allow for the fact
                # that the wavelength in the image header could be wrong and
                # in fact it should be replaced with the input value -
                # through the user will need to be warned of this and
                # also everything using the FrameProcessor interface
                # will also have to respect this!

                if (math.fabs(beam_.get_wavelength() -
                              wavelength.get_wavelength()) > 0.0001):
                    logger.info(
                        "Header wavelength for sweep %s different"
                        " to assigned value (%4.2f vs. %4.2f)",
                        name,
                        beam_.get_wavelength(),
                        wavelength.get_wavelength(),
                    )

            # also in here look at the image headers to see if we can
            # construct a mapping between exposure epoch and image ...

            images = []

            if self._frames_to_process:
                start, end = self._frames_to_process
                for j in self._images:
                    if j >= start and j <= end:
                        images.append(j)
            else:
                images = self._images

            for j in images:
                epoch = scan.get_image_epoch(j)
                if epoch == 0.0:
                    epoch = float(
                        os.stat(self._imageset.get_path(j -
                                                        images[0])).st_mtime)
                self._epoch_to_image[epoch] = j
                self._image_to_epoch[j] = epoch

            epochs = self._epoch_to_image

            logger.debug("Exposure epoch for sweep %s: %d %d" %
                         (self._template, min(epochs), max(epochs)))

        self._input_imageset = copy.deepcopy(self._imageset)

        # + get the lattice - can this be a pointer, so that when
        #   this object updates lattice it is globally-for-this-crystal
        #   updated? The lattice included directly in here includes an
        #   exact unit cell for data reduction, the crystal lattice
        #   contains an approximate unit cell which should be
        #   from the unit cells from all sweeps contained in the
        #   XCrystal. FIXME should I be using a LatticeInfo object
        #   in here? See what the Indexer interface produces. ALT:
        #   just provide an Indexer implementation "hook".
        #   See Headnote 001 above. See also _get_indexer,
        #   _get_integrater below.

        self._indexer = None
        self._refiner = None
        self._integrater = None

        # I don't need this - it is equivalent to self.getWavelength(
        # ).getCrystal().getLattice()
        # self._crystal_lattice = None

        # this means that this module will have to present largely the
        # same interface as Indexer and Integrater so that the calls
        # can be appropriately forwarded.

        # finally configure the beam if set

        if beam is not None:
            from dxtbx.model.detector_helpers import set_mosflm_beam_centre

            try:
                set_mosflm_beam_centre(
                    self.get_imageset().get_detector(),
                    self.get_imageset().get_beam(),
                    beam,
                )
            except AssertionError as e:
                logger.debug("Error setting mosflm beam centre: %s" % e)

        self._beam_centre = beam
        self._distance = distance
        self._gain = gain
        self._polarization = polarization

        self._add_detector_identification_to_cif()
Example #17
0
def exercise_mosflm_integrate():
  if not have_dials_regression:
    print "Skipping exercise_mosflm_integrate(): dials_regression not configured"
    return


  xia2_demo_data = os.path.join(dials_regression, "xia2_demo_data")
  template = os.path.join(xia2_demo_data, "insulin_1_%03i.img")

  from xia2.Wrappers.Mosflm.MosflmIndex import MosflmIndex
  from xia2.Wrappers.Mosflm.MosflmRefineCell import MosflmRefineCell
  from xia2.Wrappers.Mosflm.MosflmIntegrate import MosflmIntegrate

  # exercise basic indexing from two images
  cwd = os.path.abspath(os.curdir)
  tmp_dir = open_tmp_directory()
  os.chdir(tmp_dir)

  from xia2.Experts.FindImages import image2template_directory
  templ, directory = image2template_directory(template %1)

  indexer = MosflmIndex()
  indexer.set_images((1,45))
  indexer.set_directory(directory)
  indexer.set_template(templ)
  indexer.run()

  refiner = MosflmRefineCell()
  refiner.set_images(((1,3),(21,23), (43,45)))
  refiner.set_input_mat_file("xiaindex.mat")
  refiner.set_output_mat_file("xiarefine.mat")
  refiner.set_directory(directory)
  refiner.set_template(templ)
  refiner.set_beam_centre(indexer.get_refined_beam_centre())
  refiner.set_mosaic(
    sum(indexer.get_mosaic_spreads())/len(indexer.get_mosaic_spreads()))
  refiner.run()
  #output = ''.join(refiner.get_all_output())
  #print output

  integrater = MosflmIntegrate()
  integrater.set_image_range((1,45))
  integrater.set_input_mat_file("xiaindex.mat")
  #integrater.set_output_mat_file("xiarefine.mat")
  integrater.set_directory(directory)
  integrater.set_template(templ)
  integrater.set_beam_centre(
    tuple(float(x) for x in refiner.get_refined_beam_centre()))
  integrater.set_distance(refiner.get_refined_distance())
  integrater.set_mosaic(refiner.get_refined_mosaic())
  integrater.set_space_group_number(197)
  integrater.set_unit_cell(refiner.get_refined_unit_cell())
  integrater.run()
  hklout = integrater.get_hklout()
  assert os.path.exists(hklout)
  from iotbx.reflection_file_reader import any_reflection_file
  miller_arrays = any_reflection_file(hklout).as_miller_arrays(
    merge_equivalents=False)
  for ma in miller_arrays:
    assert ma.size() == 81011, ma.size()
  assert len(miller_arrays) == 13, len(miller_arrays)
  assert not integrater.get_bgsig_too_large()
  assert not integrater.get_getprof_error()
  assert integrater.get_batches_out() == (1, 45)
  assert integrater.get_mosaic_spreads() == [
    0.43, 0.42, 0.42, 0.41, 0.41, 0.41, 0.42, 0.42, 0.42, 0.42, 0.42, 0.42,
    0.41, 0.41, 0.41, 0.41, 0.41, 0.41, 0.41, 0.41, 0.4, 0.4, 0.4, 0.4, 0.4,
    0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4,
    0.4, 0.39, 0.39, 0.39, 0.39, 0.39]
  assert integrater.get_nref() == 81011
  assert len(integrater.get_postref_result()) == 45
  assert integrater.get_postref_result()[1] == {
    'ovrl': 0.0, 'full': 507.0, 'dist': 158.6, 'ccx': -0.01, 'yscale': 1.0,
    'sdrat': 7.5, 'tilt': 25.0, 'rsym': 0.027, 'bad': 0.0, 'i/sigi': 18.1,
    'i/sigi_out': 1.6, 'twist': 13.0, 'resid': 0.021, 'wresid': 1.1,
    'part': 1309.0, 'nsym': 18.0, 'neg': 158.0, 'ccy': -0.01, 'ccom': -0.01,
    'toff': 0.0, 'roff': 0.0}
  assert integrater.get_residuals() == [
    1.1, 0.9, 1.0, 1.0, 0.8, 0.9, 1.0, 0.8, 0.9, 0.9, 0.9, 0.9, 1.0, 1.0, 1.0,
    0.9, 0.9, 0.9, 0.9, 0.8, 1.0, 0.9, 0.8, 0.9, 1.0, 0.8, 1.0, 0.9, 0.8, 0.8,
    0.9, 0.9, 0.9, 0.9, 0.9, 1.0, 0.8, 0.9, 1.0, 0.7, 0.8, 0.9, 0.8, 0.9, 1.0]
  assert integrater.get_spot_status() \
         == 'ooooooooooooooooooooooooooooooooooooooooooooo'