def test_renumber_table_id_columns(): """Test the correct handling of duplicate table id values. Note that this function does not have the ability to update the experiment string identifier, only ensure that the table id values do not clash. """ # Test the case of two single reflection tables. rs = [ mock_reflection_file_object(id_=0).data, mock_reflection_file_object(id_=0).data, ] rs = renumber_table_id_columns(rs) assert list(rs[0]["id"]) == [-1, 0, 0] assert list(rs[0].experiment_identifiers().keys()) == [0] assert list(rs[0].experiment_identifiers().values()) == ["0"] assert list(rs[1]["id"]) == [-1, 1, 1] assert list(rs[1].experiment_identifiers().keys()) == [1] assert list(rs[1].experiment_identifiers().values()) == ["0"] # Now test the case where one reflection table contains two experiments rs = [ mock_two_reflection_file_object().data, mock_reflection_file_object(id_=0).data, ] rs = renumber_table_id_columns(rs) assert list(rs[0]["id"]) == [-1, 0, 0, 1, 1] assert list(rs[0].experiment_identifiers().keys()) == [0, 1] assert list(rs[0].experiment_identifiers().values()) == ["0", "2"] assert list(rs[1]["id"]) == [-1, 2, 2] assert list(rs[1].experiment_identifiers().keys()) == [2] assert list(rs[1].experiment_identifiers().values()) == ["0"] rs = [ mock_reflection_file_object(id_=0).data, mock_two_reflection_file_object(ids=[1, 2]).data, ] rs = renumber_table_id_columns(rs) assert list(rs[0]["id"]) == [-1, 0, 0] assert list(rs[0].experiment_identifiers().keys()) == [0] assert list(rs[0].experiment_identifiers().values()) == ["0"] assert list(rs[1]["id"]) == [-1, 1, 1, 2, 2] assert list(rs[1].experiment_identifiers().keys()) == [1, 2] assert list(rs[1].experiment_identifiers().values()) == ["1", "2"] rs = [ mock_two_reflection_file_object(ids=[1, 2]).data, mock_reflection_file_object(id_=0).data, ] rs = renumber_table_id_columns(rs) assert list(rs[0]["id"]) == [-1, 0, 0, 1, 1] assert list(rs[0].experiment_identifiers().keys()) == [0, 1] assert list(rs[0].experiment_identifiers().values()) == ["1", "2"] assert list(rs[1]["id"]) == [-1, 2, 2] assert list(rs[1].experiment_identifiers().keys()) == [2] assert list(rs[1].experiment_identifiers().values()) == ["0"]
def flatten_reflections(filename_object_list): """ Flatten a list of reflections tables A check is also made for the 'id' values in the reflection tables, which are renumbered from 0..n-1 to avoid clashes. The experiment_identifiers dict is also updated if present in the input tables. :param filename_object_list: The parameter item :return: The flattened reflection table """ tables = [o.data for o in filename_object_list] if len(tables) > 1: tables = renumber_table_id_columns(tables) return tables
def index(experiments, reflections, params): """ Index the input experiments and reflections. Args: experiments: The experiments to index reflections (list): A list of reflection tables containing strong spots params: An instance of the indexing phil scope Returns: (tuple): tuple containing: experiments: The indexed experiment list reflections (dials.array_family.flex.reflection_table): The indexed reflections Raises: ValueError: `reflections` is an empty list or `experiments` contains a combination of sequence and stills data. dials.algorithms.indexing.DialsIndexError: Indexing failed. """ if experiments.crystals()[0] is not None: known_crystal_models = experiments.crystals() else: known_crystal_models = None if len(reflections) == 0: raise ValueError("No reflection lists found in input") elif len(reflections) == 1: if "imageset_id" not in reflections[0]: reflections[0]["imageset_id"] = reflections[0]["id"] elif len(reflections) > 1: assert len(reflections) == len(experiments) for i in range(len(reflections)): reflections[i]["imageset_id"] = flex.int(len(reflections[i]), i) if i > 0: reflections[0].extend(reflections[i]) reflections = reflections[0] if params.indexing.image_range: reflections = slice_reflections(reflections, params.indexing.image_range) if len(experiments) == 1 or params.indexing.joint_indexing: indexed_experiments, indexed_reflections = _index_experiments( experiments, reflections, copy.deepcopy(params), known_crystal_models=known_crystal_models, ) else: indexed_experiments = ExperimentList() indexed_reflections = flex.reflection_table() with concurrent.futures.ProcessPoolExecutor( max_workers=params.indexing.nproc ) as pool: futures = [] for i_expt, expt in enumerate(experiments): refl = reflections.select(reflections["imageset_id"] == i_expt) refl["imageset_id"] = flex.size_t(len(refl), 0) futures.append( pool.submit( _index_experiments, ExperimentList([expt]), refl, copy.deepcopy(params), known_crystal_models=known_crystal_models, ) ) tables_list = [] for future in concurrent.futures.as_completed(futures): try: idx_expts, idx_refl = future.result() except Exception as e: print(e) else: if idx_expts is None: continue # Update the experiment ids by incrementing by the number of indexed # experiments already in the list ##FIXME below, is i_expt correct - or should it be the # index of the 'future'? idx_refl["imageset_id"] = flex.size_t(idx_refl.size(), i_expt) tables_list.append(idx_refl) indexed_experiments.extend(idx_expts) tables_list = renumber_table_id_columns(tables_list) for table in tables_list: indexed_reflections.extend(table) return indexed_experiments, indexed_reflections