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
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