def split_for_scan_range(self, experiments, reference, scan_range): """ Update experiments when scan range is set. """ from dxtbx.model.experiment.experiment_list import ExperimentList from dxtbx.model.experiment.experiment_list import Experiment from logging import info from dials.array_family import flex # Only do anything is the scan range is set if scan_range is not None and len(scan_range) > 0: # Ensure that all experiments have the same imageset and scan iset = [e.imageset for e in experiments] scan = [e.scan for e in experiments] assert all(x == iset[0] for x in iset) assert all(x == scan[0] for x in scan) # Get the imageset and scan iset = experiments[0].imageset scan = experiments[0].scan # Get the array range if scan is not None: frame10, frame11 = scan.get_array_range() assert scan.get_num_images() == len(iset) else: frame10, frame11 = (0, len(iset)) # Create the new lists new_experiments = ExperimentList() new_reference_all = reference.split_by_experiment_id() new_reference = flex.reflection_table() for i in range(len(new_reference_all) - len(experiments)): new_reference_all.append(flex.reflection_table()) assert len(new_reference_all) == len(experiments) # Loop through all the scan ranges and create a new experiment list with # the requested scan ranges. for frame00, frame01 in scan_range: assert frame01 > frame00 assert frame00 >= frame10 assert frame01 <= frame11 index0 = frame00 - frame10 index1 = index0 + (frame01 - frame00) assert index0 < index1 assert index0 >= 0 assert index1 <= len(iset) new_iset = iset[index0:index1] if scan is None: new_scan = None else: new_scan = scan[index0:index1] for i, e1 in enumerate(experiments): e2 = Experiment() e2.beam = e1.beam e2.detector = e1.detector e2.goniometer = e1.goniometer e2.crystal = e1.crystal e2.imageset = new_iset e2.scan = new_scan new_reference_all[i]["id"] = flex.int(len(new_reference_all[i]), len(new_experiments)) new_reference.extend(new_reference_all[i]) new_experiments.append(e2) experiments = new_experiments reference = new_reference # Print some information info("Modified experiment list to integrate over requested scan range") for frame00, frame01 in scan_range: info(" scan_range = %d -> %d" % (frame00, frame01)) info("") # Return the experiments return experiments, reference
def load(entry, exp_index): from dxtbx.model.experiment.experiment_list import ExperimentList from dxtbx.model.experiment.experiment_list import Experiment print "Loading NXmx" # Check file contains the feature assert("features" in entry) assert(6 in entry['features'].value) experiment_list = ExperimentList() # Find all the experiments entries = find_nx_mx_entries(entry, ".") if len(entries) > 1: entries = sorted(entries, key=lambda x: x['dials/index'].value) assert(len(entries) == len(exp_index)) for nxmx, name in zip(entries, exp_index): assert(nxmx.name == name) index = [] rotations = [] for name in exp_index: # Get the entry nxmx = entry.file[name] # Get the definition definition = nxmx['definition'] assert(definition.value == 'NXmx') assert(definition.attrs['version'] == 1) # Get dials specific stuff nx_dials = get_nx_dials(nxmx, "dials") # Set index b = nx_dials['index'].attrs['source'] d = nx_dials['index'].attrs['detector'] if "goniometer" in nx_dials['index'].attrs: g = nx_dials['index'].attrs['goniometer'] else: g = None if "scan" in nx_dials['index'].attrs: s = nx_dials['index'].attrs['scan'] else: s = None c = nx_dials['index'].attrs['sample'] index.append((b, d, g, s, c)) # Get the original orientation (dials specific) transformations = get_nx_transformations(nx_dials, "transformations") angle = transformations['angle'].value assert(transformations['angle'].attrs['transformation_type'] == 'rotation') axis = transformations['angle'].attrs['vector'] assert(tuple(transformations['angle'].attrs['offset']) == (0, 0, 0)) assert(transformations['angle'].attrs['offset_units'] == 'mm') assert(transformations['angle'].attrs['depends_on'] == '.') rotations.append((axis, angle)) # Get the tmeplate and imageset try: template = list(nx_dials['template']) image_range = None except Exception: template = nx_dials['template'].value if template == "": template = None if "range" in nx_dials['template'].attrs: image_range = nx_dials['template'].attrs['range'] else: image_range = None # Create the experiment experiment = Experiment() # Read the models experiment.beam = load_beam(nxmx) experiment.detector = load_detector(nxmx) experiment.goniometer = load_goniometer(nxmx) experiment.scan = load_scan(nxmx) experiment.crystal = load_crystal(nxmx) # Set the image range if image_range is not None and experiment.scan is not None: num = image_range[1] - image_range[0] + 1 assert(num == len(experiment.scan)) experiment.scan.set_image_range(image_range) # Return the experiment list experiment_list.append(experiment) # Convert from nexus beam direction experiment_list = convert_from_nexus_beam_direction(experiment_list,rotations) from collections import defaultdict beam = defaultdict(list) detector = defaultdict(list) goniometer = defaultdict(list) scan = defaultdict(list) crystal = defaultdict(list) for i, ind in enumerate(index): beam[ind[0]].append(i) detector[ind[1]].append(i) goniometer[ind[2]].append(i) scan[ind[3]].append(i) crystal[ind[4]].append(i) # Set all the shared beams for key, value in beam.iteritems(): b1 = experiment_list[value[0]].beam assert(all(experiment_list[v].beam == b1 for v in value[1:])) for v in value[1:]: experiment_list[v].beam = b1 # Set all the shared detectors for key, value in detector.iteritems(): d1 = experiment_list[value[0]].detector assert(all(experiment_list[v].detector == d1 for v in value[1:])) for v in value[1:]: experiment_list[v].detector = d1 # Set all the shared goniometer for key, value in goniometer.iteritems(): g1 = experiment_list[value[0]].goniometer assert(all(experiment_list[v].goniometer == g1 for v in value[1:])) for v in value[1:]: experiment_list[v].goniometer = g1 # Set all the shared scans for key, value in scan.iteritems(): s1 = experiment_list[value[0]].scan assert(all(experiment_list[v].scan == s1 for v in value[1:])) for v in value[1:]: experiment_list[v].scan = s1 # Set all the shared crystals for key, value in crystal.iteritems(): c1 = experiment_list[value[0]].crystal assert(all(experiment_list[v].crystal == c1 for v in value[1:])) for v in value[1:]: experiment_list[v].crystal = c1 return experiment_list
def split_for_scan_range(self, experiments, reference, scan_range): ''' Update experiments when scan range is set. ''' from dxtbx.model.experiment.experiment_list import ExperimentList from dxtbx.model.experiment.experiment_list import Experiment from dials.array_family import flex # Only do anything is the scan range is set if scan_range is not None and len(scan_range) > 0: # Ensure that all experiments have the same imageset and scan iset = [e.imageset for e in experiments] scan = [e.scan for e in experiments] assert (all(x == iset[0] for x in iset)) assert (all(x == scan[0] for x in scan)) # Get the imageset and scan iset = experiments[0].imageset scan = experiments[0].scan # Get the array range if scan is not None: frame10, frame11 = scan.get_array_range() assert (scan.get_num_images() == len(iset)) else: frame10, frame11 = (0, len(iset)) # Create the new lists new_experiments = ExperimentList() new_reference_all = reference.split_by_experiment_id() new_reference = flex.reflection_table() for i in range(len(new_reference_all) - len(experiments)): new_reference_all.append(flex.reflection_table()) assert (len(new_reference_all) == len(experiments)) # Loop through all the scan ranges and create a new experiment list with # the requested scan ranges. for frame00, frame01 in scan_range: assert (frame01 > frame00) assert (frame00 >= frame10) assert (frame01 <= frame11) index0 = frame00 - frame10 index1 = index0 + (frame01 - frame00) assert (index0 < index1) assert (index0 >= 0) assert (index1 <= len(iset)) new_iset = iset[index0:index1] if scan is None: new_scan = None else: new_scan = scan[index0:index1] for i, e1 in enumerate(experiments): e2 = Experiment() e2.beam = e1.beam e2.detector = e1.detector e2.goniometer = e1.goniometer e2.crystal = e1.crystal e2.imageset = new_iset e2.scan = new_scan new_reference_all[i]['id'] = flex.int( len(new_reference_all[i]), len(new_experiments)) new_reference.extend(new_reference_all[i]) new_experiments.append(e2) experiments = new_experiments reference = new_reference # Print some information logger.info( 'Modified experiment list to integrate over requested scan range' ) for frame00, frame01 in scan_range: logger.info(' scan_range = %d -> %d' % (frame00, frame01)) logger.info('') # Return the experiments return experiments, reference