Example #1
0
File: XDS.py Project: isikhar/xia2
def find_hdf5_lib(template=None):
    global __hdf5_lib
    from xia2.Applications.xia2setup import is_hdf5_name

    if template and not is_hdf5_name(template):
        return ""

    if __hdf5_lib:
        return __hdf5_lib

    from xia2.Handlers.Phil import PhilIndex
    from dials.util import Sorry

    plugin_name = PhilIndex.get_python_object().xds.hdf5_plugin

    if os.path.isabs(plugin_name):
        if not os.path.exists(plugin_name):
            raise Sorry("Cannot find plugin %s" % plugin_name)
        __hdf5_lib = "LIB=%s\n" % plugin_name
        return __hdf5_lib

    for d in os.environ["PATH"].split(os.pathsep):
        if os.path.exists(os.path.join(d, plugin_name)):
            __hdf5_lib = "LIB=%s\n" % os.path.join(d, plugin_name)
            return __hdf5_lib
    return ""
Example #2
0
    def update(self):
        """Check to see if any more frames have appeared - if they
        have update myself and reset."""

        from xia2.Applications.xia2setup import is_hdf5_name

        if is_hdf5_name(os.path.join(self._directory, self._template)):
            return

        images = find_matching_images(self._template, self._directory)

        if len(images) > len(self._images):

            self._images = images

            from xia2.Schema import load_imagesets

            imagesets = load_imagesets(
                self._template,
                self._directory,
                id_image=self._id_image,
                use_cache=False,
                reversephi=PhilIndex.params.xia2.settings.input.reverse_phi,
            )

            max_images = 0
            best_sweep = None
            for imageset in imagesets:
                scan = imageset.get_scan()
                if scan is None:
                    continue
                if imageset.get_scan().get_num_images() > max_images:
                    best_sweep = imageset

            self._imageset = best_sweep
Example #3
0
def image2template_directory(filename):
    """Separate out the template and directory from an image name."""

    directory, image = os.path.split(os.path.abspath(filename))

    from xia2.Applications.xia2setup import is_hdf5_name

    if is_hdf5_name(filename):
        return image, directory

    template = image2template(image)

    return template, directory
Example #4
0
File: XDS.py Project: isikhar/xia2
def template_to_xds(template):
    from xia2.Applications.xia2setup import is_hdf5_name

    if is_hdf5_name(template):
        # Given (e.g.) XYZ_master.h5 and data files XYZ_data_00000[0-9].h5
        # XDS expects the template XYZ_??????.h5
        assert template.endswith("master.h5"), template

        # FIXME for #401 - should look into the master file for references
        # either explicitly to child data sets or via the VDS - meantimes,
        # remove the check

        # master_file = template
        # g = glob.glob(master_file.split("master.h5")[0] + "data_*[0-9].h5")
        # g.extend(glob.glob(master_file.split("master.h5")[0] + "*[0-9].h5"))
        # assert len(g), "No associated data files found for %s" % master_file

        # we don't know what is in the master file but we know at this point
        # that the word master is in there, so... otherwise can get complicated
        # side-effects when people have a folder named e.g. data_200.
        return template.replace("master.h5", "??????.h5")

    return template.replace("#", "?")
Example #5
0
    def setup(self):
        """Set everything up..."""

        # check arguments are all ascii

        logger.debug("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)

        # 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:
            logger.debug("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)

        logger.debug("Project: %s" % params.xia2.settings.project)
        logger.debug("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"):
            logger.info(
                "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
            ])
            logger.debug(reference_geometries)
            PhilIndex.update(reference_geometries)
            logger.debug("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]
                    logger.debug("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)
            logger.debug("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_hdf5_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_hdf5_name(dataset):
                self._hdf5_master_files.append(dataset)
                if start_end:
                    logger.debug("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:
                    logger.debug("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)

                logger.debug("Interpreted from image %s:" % dataset)
                logger.debug("Template %s" % template)
                logger.debug("Directory %s" % directory)

                if start_end:
                    logger.debug("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:
                    logger.debug("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", "w") 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", "w") as f:
            f.write(PhilIndex.get_diff().as_str())
            f.write(
                os.linesep
            )  # temporarily required for https://github.com/dials/dials/issues/522

        logger.debug("\nDifference PHIL:")
        logger.debug(PhilIndex.get_diff().as_str())

        logger.debug("Working PHIL:")
        logger.debug(PhilIndex.working_phil.as_str())

        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)