Пример #1
0
    def get_imageset(
        Class,
        filenames,
        beam=None,
        detector=None,
        goniometer=None,
        scan=None,
        as_sweep=False,
        as_imageset=False,
        single_file_indices=None,
        format_kwargs=None,
        template=None,
        check_format=True,
        lazy=False,
    ):
        """
        Factory method to create an imageset

        """
        from dxtbx.imageset import ImageSetData
        from dxtbx.imageset import ImageSweep
        from os.path import abspath
        from scitbx.array_family import flex

        if isinstance(filenames, str):
            filenames = [filenames]
        elif len(filenames) > 1:
            assert len(set(filenames)) == 1
            filenames = filenames[0:1]

        # Make filenames absolute
        filenames = map(abspath, filenames)

        # Make it a dictionary
        if format_kwargs is None:
            format_kwargs = {}

        # If get_num_images hasn't been implemented, we need indices for number of images
        if Class.get_num_images == FormatMultiImage.get_num_images:
            assert single_file_indices is not None
            assert min(single_file_indices) >= 0
            num_images = max(single_file_indices) + 1
        else:
            num_images = None

        # Get some information from the format class
        reader = Class.get_reader()(filenames, num_images=num_images, **format_kwargs)
        masker = Class.get_masker()(filenames, num_images=num_images, **format_kwargs)

        # Get the format instance
        assert len(filenames) == 1
        if check_format is True:
            format_instance = Class(filenames[0], **format_kwargs)
        else:
            format_instance = None
            if not as_sweep:
                lazy = True

        # Read the vendor type
        if check_format is True:
            vendor = format_instance.get_vendortype()
        else:
            vendor = ""

        # Get the format kwargs
        params = format_kwargs

        # Check if we have a sweep

        # Make sure only 1 or none is set
        assert [as_imageset, as_sweep].count(True) < 2
        if as_imageset:
            is_sweep = False
        elif as_sweep:
            is_sweep = True
        else:
            if scan is None and format_instance is None:
                raise RuntimeError(
                    """
          One of the following needs to be set
            - as_imageset=True
            - as_sweep=True
            - scan
            - check_format=True
      """
                )
            if scan is None:
                test_scan = format_instance.get_scan()
            else:
                test_scan = scan
            if test_scan is not None and test_scan.get_oscillation()[1] != 0:
                is_sweep = True
            else:
                is_sweep = False

        assert not (as_sweep and lazy), "No lazy support for sweeps"

        if single_file_indices is not None:
            single_file_indices = flex.size_t(single_file_indices)

        # Create an imageset or sweep
        if not is_sweep:

            # Use imagesetlazy
            # Setup ImageSetLazy and just return it. No models are set.
            if lazy:
                from dxtbx.imageset import ImageSetLazy

                iset = ImageSetLazy(
                    ImageSetData(
                        reader=reader,
                        masker=masker,
                        vendor=vendor,
                        params=params,
                        format=Class,
                    ),
                    indices=single_file_indices,
                )
                return iset
            # Create the imageset
            from dxtbx.imageset import ImageSet

            iset = ImageSet(
                ImageSetData(
                    reader=reader,
                    masker=masker,
                    vendor=vendor,
                    params=params,
                    format=Class,
                ),
                indices=single_file_indices,
            )

            # If any are None then read from format
            if [beam, detector, goniometer, scan].count(None) != 0:

                # Get list of models
                beam = []
                detector = []
                goniometer = []
                scan = []
                for i in range(format_instance.get_num_images()):
                    beam.append(format_instance.get_beam(i))
                    detector.append(format_instance.get_detector(i))
                    goniometer.append(format_instance.get_goniometer(i))
                    scan.append(format_instance.get_scan(i))

            if single_file_indices is None:
                single_file_indices = list(range(format_instance.get_num_images()))

            # Set the list of models
            for i in range(len(single_file_indices)):
                iset.set_beam(beam[single_file_indices[i]], i)
                iset.set_detector(detector[single_file_indices[i]], i)
                iset.set_goniometer(goniometer[single_file_indices[i]], i)
                iset.set_scan(scan[single_file_indices[i]], i)

        else:

            # Get the template
            template = filenames[0]

            # Check indices are sequential
            if single_file_indices is not None:
                assert all(
                    i + 1 == j
                    for i, j in zip(single_file_indices[:-1], single_file_indices[1:])
                )
                num_images = len(single_file_indices)
            else:
                num_images = format_instance.get_num_images()

            # Check the scan makes sense - we must want to use <= total images
            if scan is not None:
                assert scan.get_num_images() <= num_images

            # If any are None then read from format
            if beam is None:
                beam = format_instance.get_beam()
            if detector is None:
                detector = format_instance.get_detector()
            if goniometer is None:
                goniometer = format_instance.get_goniometer()
            if scan is None:
                scan = format_instance.get_scan()
                if scan is not None:
                    for f in filenames[1:]:
                        format_instance = Class(f, **format_kwargs)
                        scan += format_instance.get_scan()

            isetdata = ImageSetData(
                reader=reader,
                masker=masker,
                vendor=vendor,
                params=params,
                format=Class,
                template=template,
            )

            # Create the sweep
            iset = ImageSweep(
                isetdata,
                beam=beam,
                detector=detector,
                goniometer=goniometer,
                scan=scan,
                indices=single_file_indices,
            )

        # Return the imageset
        return iset
Пример #2
0
    def get_imageset(
        cls,
        filenames,
        beam=None,
        detector=None,
        goniometer=None,
        scan=None,
        as_sequence=False,
        as_imageset=False,
        single_file_indices=None,
        format_kwargs=None,
        template=None,
        check_format=True,
        lazy=False,
    ):
        """
        Factory method to create an imageset

        """
        if isinstance(filenames, str):
            filenames = [filenames]
        elif len(filenames) > 1:
            assert len(set(filenames)) == 1
            filenames = filenames[0:1]

        # Make filenames absolute
        filenames = [os.path.abspath(x) for x in filenames]

        # Make it a dictionary
        if format_kwargs is None:
            format_kwargs = {}

        # If get_num_images hasn't been implemented, we need indices for number of images
        if cls.get_num_images == FormatMultiImage.get_num_images:
            assert single_file_indices is not None
            assert min(single_file_indices) >= 0
            num_images = max(single_file_indices) + 1
        else:
            num_images = None

        # Get the format instance
        assert len(filenames) == 1
        if check_format is True:
            format_instance = cls(filenames[0], **format_kwargs)
            if num_images is None and not lazy:
                # As we now have the actual format class we can get the number
                # of images from here. This saves having to create another
                # format class instance in the Reader() constructor
                # NOTE: Having this information breaks internal assumptions in
                #       *Lazy classes, so they have to figure this out in
                #       their own time.
                num_images = format_instance.get_num_images()
        else:
            format_instance = None
            if not as_sequence:
                lazy = True

        # Get some information from the format class
        reader = cls.get_reader()(filenames, num_images=num_images, **format_kwargs)

        # Read the vendor type
        if check_format is True:
            vendor = format_instance.get_vendortype()
        else:
            vendor = ""

        # Get the format kwargs
        params = format_kwargs

        # Check if we have a sequence

        # Make sure only 1 or none is set
        assert [as_imageset, as_sequence].count(True) < 2
        if as_imageset:
            is_sequence = False
        elif as_sequence:
            is_sequence = True
        else:
            if scan is None and format_instance is None:
                raise RuntimeError(
                    """
          One of the following needs to be set
            - as_imageset=True
            - as_sequence=True
            - scan
            - check_format=True
      """
                )
            if scan is None:
                test_scan = format_instance.get_scan()
            else:
                test_scan = scan
            if test_scan is not None:
                is_sequence = True
            else:
                is_sequence = False

        assert not (as_sequence and lazy), "No lazy support for sequences"

        if single_file_indices is not None:
            single_file_indices = flex.size_t(single_file_indices)

        # Create an imageset or sequence
        if not is_sequence:

            # Use imagesetlazy
            # Setup ImageSetLazy and just return it. No models are set.
            if lazy:
                iset = ImageSetLazy(
                    ImageSetData(
                        reader=reader,
                        masker=None,
                        vendor=vendor,
                        params=params,
                        format=cls,
                    ),
                    indices=single_file_indices,
                )
                return iset
            # Create the imageset
            iset = ImageSet(
                ImageSetData(
                    reader=reader, masker=None, vendor=vendor, params=params, format=cls
                ),
                indices=single_file_indices,
            )

            # If any are None then read from format
            if [beam, detector, goniometer, scan].count(None) != 0:

                # Get list of models
                beam = []
                detector = []
                goniometer = []
                scan = []
                for i in range(format_instance.get_num_images()):
                    beam.append(format_instance.get_beam(i))
                    detector.append(format_instance.get_detector(i))
                    goniometer.append(format_instance.get_goniometer(i))
                    scan.append(format_instance.get_scan(i))

            if single_file_indices is None:
                single_file_indices = list(range(format_instance.get_num_images()))

            # Set the list of models
            for i in range(len(single_file_indices)):
                iset.set_beam(beam[single_file_indices[i]], i)
                iset.set_detector(detector[single_file_indices[i]], i)
                iset.set_goniometer(goniometer[single_file_indices[i]], i)
                iset.set_scan(scan[single_file_indices[i]], i)

        else:

            # Get the template
            template = filenames[0]

            # Check indices are sequential
            if single_file_indices is not None:
                assert all(
                    i + 1 == j
                    for i, j in zip(single_file_indices[:-1], single_file_indices[1:])
                )
                num_images = len(single_file_indices)
            else:
                num_images = format_instance.get_num_images()

            # Check the scan makes sense - we must want to use <= total images
            if scan is not None:
                assert scan.get_num_images() <= num_images

            # If any are None then read from format
            if beam is None:
                beam = format_instance.get_beam()
            if detector is None:
                detector = format_instance.get_detector()
            if goniometer is None:
                goniometer = format_instance.get_goniometer()
            if scan is None:
                scan = format_instance.get_scan()
                if scan is not None:
                    for f in filenames[1:]:
                        format_instance = cls(f, **format_kwargs)
                        scan += format_instance.get_scan()

            # Create the masker
            if format_instance is not None:
                masker = format_instance.get_masker(goniometer=goniometer)
            else:
                masker = None

            isetdata = ImageSetData(
                reader=reader,
                masker=masker,
                vendor=vendor,
                params=params,
                format=cls,
                template=template,
            )

            # Create the sequence
            iset = ImageSequence(
                isetdata,
                beam=beam,
                detector=detector,
                goniometer=goniometer,
                scan=scan,
                indices=single_file_indices,
            )

        if format_instance is not None:
            static_mask = format_instance.get_static_mask()
            if static_mask is not None:
                if not iset.external_lookup.mask.data.empty():
                    for m1, m2 in zip(static_mask, iset.external_lookup.mask.data):
                        m1 &= m2.data()
                    iset.external_lookup.mask.data = ImageBool(static_mask)
                else:
                    iset.external_lookup.mask.data = ImageBool(static_mask)

        return iset