Beispiel #1
0
def write_xinfo(filename, directories, template=None, hdf5_master_files=None):
    global target_template

    target_template = template

    settings = PhilIndex.get_python_object().xia2.settings
    crystal = settings.crystal

    if not os.path.isabs(filename):
        filename = os.path.abspath(filename)

    directory = os.path.join(os.getcwd(), crystal, 'setup')

    try:
        os.makedirs(directory)
    except OSError as e:
        if not 'File exists' in str(e):
            raise

    # FIXME should I have some exception handling in here...?

    start = os.getcwd()
    os.chdir(directory)

    # if we have given a template and directory on the command line, just
    # look there (i.e. not in the subdirectories)

    import libtbx.load_env
    if CommandLine.get_template() and CommandLine.get_directory():
        templates = set()
        for directory in CommandLine.get_directory():
            templates.update(visit(None, directory, os.listdir(directory)))
        get_sweeps(templates)
    elif hdf5_master_files is not None:
        get_sweeps(hdf5_master_files)
    else:
        rummage(directories)

    fout = open(filename, 'w')
    print_sweeps(fout)

    # change back directory c/f bug # 2693 - important for error files...
    os.chdir(start)
Beispiel #2
0
def run():
    streams_off()

    # test to see if sys.argv[-2] + path is a valid path - to work around
    # spaced command lines

    argv = CommandLine.get_argv()

    if not CommandLine.get_directory():

        directories = []

        for arg in argv:
            if os.path.isdir(arg):
                directories.append(os.path.abspath(arg))

        if not directories:
            raise RuntimeError('directory not found in arguments')

    else:
        directories = [CommandLine.get_directory()]

    directories = [os.path.abspath(d) for d in directories]

    # perhaps move to a new directory...
    settings = PhilIndex.get_python_object().xia2.settings
    crystal = settings.crystal

    with open(os.path.join(os.getcwd(), 'automatic.xinfo'), 'w') as fout:
        start = os.path.abspath(os.getcwd())
        directory = os.path.join(os.getcwd(), crystal, 'setup')
        try:
            os.makedirs(directory)
        except OSError as e:
            if not 'File exists' in str(e):
                raise e
        os.chdir(directory)

        rummage(directories)
        print_sweeps(fout)
Beispiel #3
0
def write_xinfo(filename, directories, template=None, hdf5_master_files=None):
    global target_template

    target_template = template

    settings = PhilIndex.get_python_object().xia2.settings
    crystal = settings.crystal

    if not os.path.isabs(filename):
        filename = os.path.abspath(filename)

    directory = os.path.join(os.getcwd(), crystal, "setup")

    try:
        os.makedirs(directory)
    except OSError as e:
        if "File exists" not in str(e):
            raise

    # if we have given a template and directory on the command line, just
    # look there (i.e. not in the subdirectories)

    if CommandLine.get_template() and CommandLine.get_directory():
        # xia2 image=$(dials.data get -q x4wide)/X4_wide_M1S4_2_0001.cbf
        templates = set()
        for directory in CommandLine.get_directory():
            templates.update(visit(directory, os.listdir(directory)))
        sweeps = _get_sweeps(templates)
    elif hdf5_master_files is not None:
        # xia2 image=$(dials.data get -q vmxi_thaumatin)/image_15799_master.h5
        sweeps = _get_sweeps(hdf5_master_files)
    else:
        # xia2 $(dials.data get -q x4wide)
        sweeps = _rummage(directories)

    with open(filename, "w") as fout:
        _write_sweeps(sweeps, fout)
Beispiel #4
0
  def json_object(self, command_line=''):

    result = {}

    for crystal in sorted(self._crystals):
      xcrystal = self._crystals[crystal]

      cell = xcrystal.get_cell()
      spacegroup = xcrystal.get_likely_spacegroups()[0]

      result['AutoProc'] = {}
      tmp = result['AutoProc']

      tmp['spaceGroup'] = spacegroup
      for name, value in zip(['a', 'b', 'c', 'alpha', 'beta', 'gamma'], cell):
        tmp['refinedCell_%s' % name] = value

      result['AutoProcScalingContainer'] = {}
      tmp = result['AutoProcScalingContainer']
      tmp['AutoProcScaling'] = {
          'recordTimeStamp': time.strftime('%Y-%m-%d %H:%M:%S',
                                           time.localtime())
      }

      statistics_all = xcrystal.get_statistics()
      reflection_files = xcrystal.get_scaled_merged_reflections()

      wavelength_names = xcrystal.get_wavelength_names()

      for key in statistics_all.keys():
        pname, xname, dname = key

        # FIXME should assert that the dname is a
        # valid wavelength name

        available = statistics_all[key].keys()

        stats = []
        keys = [
            'High resolution limit',
            'Low resolution limit',
            'Completeness',
            'Multiplicity',
            'I/sigma',
            'Rmerge(I+/-)',
            'CC half',
            'Anomalous completeness',
            'Anomalous correlation',
            'Anomalous multiplicity',
            'Total observations',
            'Total unique',
            'Rmeas(I)',
            'Rmeas(I+/-)',
            'Rpim(I)',
            'Rpim(I+/-)',
            'Partial Bias'
            ]

        for k in keys:
          if k in available:
            stats.append(k)

        xwavelength = xcrystal.get_xwavelength(dname)
        sweeps = xwavelength.get_sweeps()

        tmp['AutoProcScalingStatistics'] = []
        tmp2 = tmp['AutoProcScalingStatistics']

        for j, name in enumerate(
            ['overall', 'innerShell', 'outerShell']):
          statistics_cache = {'scalingStatisticsType':name}

          for s in stats:

            if s in self._name_map:
              n = self._name_map[s]
            else:
              continue

            if isinstance(statistics_all[key][s], type([])):
              statistics_cache[n] = statistics_all[key][s][j]
            elif isinstance(statistics_all[key][s], type(())):
              statistics_cache[n] = statistics_all[key][s][j]

          tmp2.append(statistics_cache)

        tmp['AutoProcIntegrationContainer'] = []
        tmp2 = tmp['AutoProcIntegrationContainer']
        for sweep in sweeps:
          if '#' in sweep.get_template():
            image_name = sweep.get_image_name(0)
          else:
            image_name = os.path.join(sweep.get_directory(),
                                      sweep.get_template())
          cell = sweep.get_integrater_cell()
          intgr_tmp = {}
          for name, value in zip(['a', 'b', 'c', 'alpha', 'beta', 'gamma'],
                                 cell):
            intgr_tmp['cell_%s' % name] = value

          # FIXME this is naughty
          indxr = sweep._get_indexer()
          intgr = sweep._get_integrater()

          start, end = intgr.get_integrater_wedge()

          intgr_tmp['startImageNumber'] = start
          intgr_tmp['endImageNumber'] = end

          intgr_tmp['refinedDetectorDistance'] = indxr.get_indexer_distance()

          beam = indxr.get_indexer_beam_centre()

          intgr_tmp['refinedXBeam'] = beam[0]
          intgr_tmp['refinedYBeam'] = beam[1]

          tmp2.append(
            {'Image':{'fileName':os.path.split(image_name)[-1],
                      'fileLocation':sanitize(os.path.split(image_name)[0])},
             'AutoProcIntegration': intgr_tmp})

      # file unpacking nonsense
      result['AutoProcProgramContainer'] = {}
      tmp = result['AutoProcProgramContainer']
      tmp2 = {}

      if not command_line:
        from xia2.Handlers.CommandLine import CommandLine
        command_line = CommandLine.get_command_line()

      tmp2['processingCommandLine'] = sanitize(command_line)
      tmp2['processingProgram'] = 'xia2'

      tmp['AutoProcProgram'] = tmp2
      tmp['AutoProcProgramAttachment'] = []
      tmp2 = tmp['AutoProcProgramAttachment']

      from xia2.Handlers.Environment import Environment
      data_directory = Environment.generate_directory('DataFiles')

      for k in reflection_files:
        reflection_file = reflection_files[k]

        if not isinstance(reflection_file, type('')):
          continue

        reflection_file = FileHandler.get_data_file(reflection_file)
        basename = os.path.basename(reflection_file)

        if os.path.isfile(os.path.join(data_directory, basename)):
          # Use file in DataFiles directory in preference (if it exists)
          reflection_file = os.path.join(data_directory, basename)

        tmp2.append({
          'fileType': 'Result',
          'fileName': os.path.split(reflection_file)[-1],
          'filePath': sanitize(os.path.split(reflection_file)[0]),
        })

      tmp2.append({'fileType':'Log',
                   'fileName':'xia2.txt',
                   'filePath':sanitize(os.getcwd())})

    return result
Beispiel #5
0
  def write_xml(self, file, command_line=''):

    fout = open(file, 'w')

    fout.write('<?xml version="1.0"?>')
    fout.write('<AutoProcContainer>\n')

    for crystal in sorted(self._crystals):
      xcrystal = self._crystals[crystal]

      cell = xcrystal.get_cell()
      spacegroup = xcrystal.get_likely_spacegroups()[0]

      fout.write('<AutoProc><spaceGroup>%s</spaceGroup>' % spacegroup)
      self.write_refined_cell(fout, cell)
      fout.write('</AutoProc>')

      fout.write('<AutoProcScalingContainer>')
      fout.write('<AutoProcScaling>')
      self.write_date(fout)
      fout.write('</AutoProcScaling>')

      statistics_all = xcrystal.get_statistics()
      reflection_files = xcrystal.get_scaled_merged_reflections()

      wavelength_names = xcrystal.get_wavelength_names()

      for key in statistics_all.keys():
        pname, xname, dname = key

        # FIXME should assert that the dname is a
        # valid wavelength name

        available = statistics_all[key].keys()

        stats = []
        keys = [
            'High resolution limit',
            'Low resolution limit',
            'Completeness',
            'Multiplicity',
            'I/sigma',
            'Rmerge(I+/-)',
            'CC half',
            'Anomalous completeness',
            'Anomalous correlation',
            'Anomalous multiplicity',
            'Total observations',
            'Total unique',
            'Rmeas(I)',
            'Rmeas(I+/-)',
            'Rpim(I)',
            'Rpim(I+/-)',
            'Partial Bias'
            ]

        for k in keys:
          if k in available:
            stats.append(k)

        xwavelength = xcrystal.get_xwavelength(dname)
        sweeps = xwavelength.get_sweeps()

        for j, name in enumerate(['overall', 'innerShell', 'outerShell']):
          statistics_cache = {}

          for s in stats:
            if isinstance(statistics_all[key][s], type([])):
              statistics_cache[s] = statistics_all[key][s][j]
            elif isinstance(statistics_all[key][s], type(())):
              statistics_cache[s] = statistics_all[key][s][j]

          # send these to be written out
          self.write_scaling_statistics(fout, name, statistics_cache)

        for sweep in sweeps:
          fout.write('<AutoProcIntegrationContainer>\n')
          if '#' in sweep.get_template():
            image_name = sweep.get_image_name(0)
          else:
            image_name = os.path.join(sweep.get_directory(),
                                      sweep.get_template())
          fout.write('<Image><fileName>%s</fileName>' % \
                     os.path.split(image_name)[-1])
          fout.write('<fileLocation>%s</fileLocation></Image>' %
                     sanitize(os.path.split(image_name)[0]))
          fout.write('<AutoProcIntegration>\n')
          cell = sweep.get_integrater_cell()
          self.write_cell(fout, cell)

          # FIXME this is naughty
          intgr = sweep._get_integrater()

          start, end = intgr.get_integrater_wedge()

          fout.write('<startImageNumber>%d</startImageNumber>' % \
                     start)

          fout.write('<endImageNumber>%d</endImageNumber>' % \
                     end)

          # FIXME this is naughty
          indxr = sweep._get_indexer()

          fout.write(
              '<refinedDetectorDistance>%f</refinedDetectorDistance>' % \
              indxr.get_indexer_distance())

          beam = indxr.get_indexer_beam_centre()

          fout.write('<refinedXBeam>%f</refinedXBeam>' % beam[0])
          fout.write('<refinedYBeam>%f</refinedYBeam>' % beam[1])

          fout.write('</AutoProcIntegration>\n')
          fout.write('</AutoProcIntegrationContainer>\n')

      fout.write('</AutoProcScalingContainer>')

      # file unpacking nonsense

      if not command_line:
        from xia2.Handlers.CommandLine import CommandLine
        command_line = CommandLine.get_command_line()

      fout.write('<AutoProcProgramContainer><AutoProcProgram>')
      fout.write('<processingCommandLine>%s</processingCommandLine>' \
                 % sanitize(command_line))
      fout.write('<processingPrograms>xia2</processingPrograms>')
      fout.write('</AutoProcProgram>')

      from xia2.Handlers.Environment import Environment
      data_directory = Environment.generate_directory('DataFiles')
      log_directory = Environment.generate_directory('LogFiles')

      for k in reflection_files:

        reflection_file = reflection_files[k]

        if not isinstance(reflection_file, type('')):
          continue

        reflection_file = FileHandler.get_data_file(reflection_file)

        basename = os.path.basename(reflection_file)
        if os.path.isfile(os.path.join(data_directory, basename)):
          # Use file in DataFiles directory in preference (if it exists)
          reflection_file = os.path.join(data_directory, basename)

        fout.write('<AutoProcProgramAttachment><fileType>Result')
        fout.write('</fileType><fileName>%s</fileName>' % \
                   os.path.split(reflection_file)[-1])
        fout.write('<filePath>%s</filePath>' % \
                   sanitize(os.path.split(reflection_file)[0]))
        fout.write('</AutoProcProgramAttachment>\n')

      import glob
      g = glob.glob(os.path.join(log_directory, '*merging-statistics.json'))
      for merging_stats_json in g:
        fout.write('<AutoProcProgramAttachment><fileType>Graph')
        fout.write('</fileType><fileName>%s</fileName>' %
                   os.path.split(merging_stats_json)[-1])
        fout.write('<filePath>%s</filePath>' % sanitize(log_directory))
        fout.write('</AutoProcProgramAttachment>\n')

      # add the xia2.txt file...

      fout.write('<AutoProcProgramAttachment><fileType>Log')
      fout.write('</fileType><fileName>xia2.txt</fileName>')
      fout.write('<filePath>%s</filePath>' % sanitize(os.getcwd()))
      fout.write('</AutoProcProgramAttachment>\n')

      fout.write('</AutoProcProgramContainer>')

    fout.write('</AutoProcContainer>\n')
    fout.close()
Beispiel #6
0
def print_sweeps(out=sys.stdout):

    global known_sweeps, latest_sequence

    sweeplists = known_sweeps.keys()
    assert len(sweeplists) > 0, "no sweeps found"
    sweeplists.sort()

    # sort sweeplist based on epoch of first image of each sweep
    import operator
    epochs = [
        known_sweeps[sweep][0].get_imageset().get_scan().get_epochs()[0]
        for sweep in sweeplists
    ]

    if len(epochs) != len(set(epochs)):
        Debug.write(
            'Duplicate epochs found. Trying to correct epoch information.')
        cumulativedelta = 0.0
        for sweep in sweeplists:
            known_sweeps[sweep][0].get_imageset().get_scan().set_epochs(
                known_sweeps[sweep][0].get_imageset().get_scan().get_epochs() +
                cumulativedelta)
            # could change the image epoch information individually, but only
            # the information from the first image is used at this time.
            cumulativedelta += sum(
                known_sweeps[sweep]
                [0].get_imageset().get_scan().get_exposure_times())
        epochs = [
            known_sweeps[sweep][0].get_imageset().get_scan().get_epochs()[0]
            for sweep in sweeplists
        ]

        if len(epochs) != len(set(epochs)):
            Debug.write('Duplicate epoch information remains.')
        # This should only happen with incorrect exposure time information.

    sweeplists, epochs = zip(
        *sorted(zip(sweeplists, epochs), key=operator.itemgetter(1)))

    # analysis pass

    wavelengths = []

    settings = PhilIndex.get_python_object().xia2.settings
    wavelength_tolerance = settings.wavelength_tolerance
    min_images = settings.input.min_images
    min_oscillation_range = settings.input.min_oscillation_range

    for sweep in sweeplists:
        sweeps = known_sweeps[sweep]

        # sort on exposure epoch
        epochs = [s.get_imageset().get_scan().get_epochs()[0] for s in sweeps]
        sweeps, epochs = zip(
            *sorted(zip(sweeps, epochs), key=operator.itemgetter(1)))
        for s in sweeps:

            if len(s.get_images()) < min_images:
                Debug.write('Rejecting sweep %s:' % s.get_template())
                Debug.write(
                    '  Not enough images (found %i, require at least %i)' %
                    (len(s.get_images()), min_images))
                continue

            oscillation_range = s.get_imageset().get_scan(
            ).get_oscillation_range()
            width = oscillation_range[1] - oscillation_range[0]
            if width < min_oscillation_range:
                Debug.write('Rejecting sweep %s:' % s.get_template())
                Debug.write(
                    '  Too narrow oscillation range (found %i, require at least %i)'
                    % (width, min_oscillation_range))
                continue

            wavelength = s.get_wavelength()

            if not wavelength in wavelengths:
                have_wavelength = False
                for w in wavelengths:
                    if abs(w - wavelength) < wavelength_tolerance:
                        have_wavelength = True
                        s.set_wavelength(w)
                if not have_wavelength:
                    wavelengths.append(wavelength)

    assert len(wavelengths), "No sweeps found matching criteria"

    wavelength_map = {}

    project = settings.project
    crystal = settings.crystal

    out.write('BEGIN PROJECT %s\n' % project)
    out.write('BEGIN CRYSTAL %s\n' % crystal)

    out.write('\n')

    # check to see if a user spacegroup has been assigned - if it has,
    # copy it in...

    if settings.space_group is not None:
        out.write('USER_SPACEGROUP %s\n' %
                  settings.space_group.type().lookup_symbol())
        out.write('\n')

    if settings.unit_cell is not None:
        out.write('USER_CELL %.2f %.2f %.2f %.2f %.2f %.2f\n' % \
                  settings.unit_cell.parameters())
        out.write('\n')

    freer_file = PhilIndex.params.xia2.settings.scale.freer_file
    if freer_file is not None:
        out.write('FREER_FILE %s\n' %
                  PhilIndex.params.xia2.settings.scale.freer_file)
        out.write('\n')

    if latest_sequence:
        out.write('BEGIN AA_SEQUENCE\n')
        out.write('\n')
        for sequence_chunk in [latest_sequence[i:i + 60] \
                               for i in range(0, len(latest_sequence), 60)]:
            out.write('%s\n' % sequence_chunk)
        out.write('\n')
        out.write('END AA_SEQUENCE\n')
        out.write('\n')

    if settings.input.atom:
        out.write('BEGIN HA_INFO\n')
        out.write('ATOM %s\n' % settings.input.atom.lower())
        out.write('END HA_INFO\n')
        out.write('\n')
    elif settings.input.anomalous:
        out.write('BEGIN HA_INFO\n')
        out.write('ATOM X\n')
        out.write('END HA_INFO\n')
        out.write('\n')

    for j in range(len(wavelengths)):
        anomalous = settings.input.anomalous
        if settings.input.atom is not None:
            anomalous = True
        if len(wavelengths) == 1 and anomalous:
            name = 'SAD'
        elif len(wavelengths) == 1:
            name = 'NATIVE'
        else:
            name = 'WAVE%d' % (j + 1)

        wavelength_map[wavelengths[j]] = name

        out.write('BEGIN WAVELENGTH %s\n' % name)

        dmin = PhilIndex.params.xia2.settings.resolution.d_min
        dmax = PhilIndex.params.xia2.settings.resolution.d_max

        if dmin and dmax:
            out.write('RESOLUTION %f %f\n' % (dmin, dmax))
        elif dmin:
            out.write('RESOLUTION %f\n' % dmin)

        out.write('WAVELENGTH %f\n' % wavelengths[j])

        out.write('END WAVELENGTH %s\n' % name)
        out.write('\n')

    j = 0
    for sweep in sweeplists:
        sweeps = known_sweeps[sweep]
        # sort on exposure epoch
        epochs = [s.get_imageset().get_scan().get_epochs()[0] for s in sweeps]
        sweeps, epochs = zip(
            *sorted(zip(sweeps, epochs), key=operator.itemgetter(1)))
        for s in sweeps:

            # require at least n images to represent a sweep...
            if len(s.get_images()) < min_images:
                Debug.write('Rejecting sweep %s:' % s.get_template())
                Debug.write(
                    '  Not enough images (found %i, require at least %i)' %
                    (len(s.get_images()), min_images))
                continue

            oscillation_range = s.get_imageset().get_scan(
            ).get_oscillation_range()
            width = oscillation_range[1] - oscillation_range[0]
            if width < min_oscillation_range:
                Debug.write('Rejecting sweep %s:' % s.get_template())
                Debug.write(
                    '  Too narrow oscillation range (found %i, require at least %i)'
                    % (width, min_oscillation_range))
                continue

            key = os.path.join(s.get_directory(), s.get_template())
            if CommandLine.get_start_ends(key):
                start_ends = CommandLine.get_start_ends(key)
            else:
                start_ends = [(min(s.get_images()), max(s.get_images()))]

            for start_end in start_ends:
                j += 1
                name = 'SWEEP%d' % j

                out.write('BEGIN SWEEP %s\n' % name)

                if PhilIndex.params.xia2.settings.input.reverse_phi:
                    out.write('REVERSEPHI\n')

                out.write('WAVELENGTH %s\n' %
                          wavelength_map[s.get_wavelength()])

                out.write('DIRECTORY %s\n' % s.get_directory())
                imgset = s.get_imageset()
                out.write('IMAGE %s\n' % os.path.split(imgset.get_path(0))[-1])
                out.write('START_END %d %d\n' % start_end)

                # really don't need to store the epoch in the xinfo file
                # out.write('EPOCH %d\n' % int(s.get_collect()[0]))
                if not settings.trust_beam_centre:
                    interactive = False
                    if PhilIndex.params.xia2.settings.interactive == True:
                        interactive = True
                        PhilIndex.params.xia2.settings.interactive = False
                        PhilIndex.get_python_object()
                    beam_centre = compute_beam_centre(s)
                    if beam_centre:
                        out.write('BEAM %6.2f %6.2f\n' % tuple(beam_centre))
                    PhilIndex.params.xia2.settings.interactive = interactive
                    PhilIndex.get_python_object()

                if settings.detector_distance is not None:
                    out.write('DISTANCE %.2f\n' % settings.detector_distance)

                out.write('END SWEEP %s\n' % name)

                out.write('\n')

    out.write('END CRYSTAL %s\n' % crystal)
    out.write('END PROJECT %s\n' % project)
Beispiel #7
0
def get_command_line():
    from xia2.Handlers.CommandLine import CommandLine

    CommandLine.print_command_line()

    if not CommandLine.get_xinfo():
        # write an xinfo file then
        xinfo = os.path.join(os.getcwd(), "automatic.xinfo")

        argv = CommandLine.get_argv()

        if not CommandLine.get_directory():

            directories = []

            for arg in argv:
                if os.path.isdir(arg):
                    directories.append(os.path.abspath(arg))

            if not directories and not CommandLine.get_hdf5_master_files():
                raise Sorry(
                    "No image directory found in command line arguments. "
                    "Run xia2 without any options for command line help."
                )

        else:
            directories = CommandLine.get_directory()

        directories = [os.path.abspath(d) for d in directories]
        from xia2.Applications.xia2setup import write_xinfo

        check_hdf5_master_files(CommandLine.get_hdf5_master_files())

        if CommandLine.get_template() or CommandLine.get_hdf5_master_files():
            write_xinfo(
                xinfo,
                directories,
                template=CommandLine.get_template(),
                hdf5_master_files=CommandLine.get_hdf5_master_files(),
            )
        else:
            write_xinfo(xinfo, directories)

        CommandLine.set_xinfo(xinfo)

    return CommandLine
Beispiel #8
0
    def json_object(self, command_line=""):

        result = {}

        for crystal in sorted(self._crystals):
            xcrystal = self._crystals[crystal]

            cell = xcrystal.get_cell()
            spacegroup = xcrystal.get_likely_spacegroups()[0]

            result["AutoProc"] = {}
            tmp = result["AutoProc"]

            tmp["spaceGroup"] = spacegroup
            for name, value in zip(["a", "b", "c", "alpha", "beta", "gamma"],
                                   cell):
                tmp["refinedCell_%s" % name] = value

            result["AutoProcScalingContainer"] = {}
            tmp = result["AutoProcScalingContainer"]
            tmp["AutoProcScaling"] = {
                "recordTimeStamp":
                time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            }

            statistics_all = xcrystal.get_statistics()
            reflection_files = xcrystal.get_scaled_merged_reflections()

            for key in list(statistics_all.keys()):
                pname, xname, dname = key

                # FIXME should assert that the dname is a
                # valid wavelength name

                keys = [
                    "High resolution limit",
                    "Low resolution limit",
                    "Completeness",
                    "Multiplicity",
                    "I/sigma",
                    "Rmerge(I+/-)",
                    "CC half",
                    "Anomalous completeness",
                    "Anomalous correlation",
                    "Anomalous multiplicity",
                    "Total observations",
                    "Total unique",
                    "Rmeas(I)",
                    "Rmeas(I+/-)",
                    "Rpim(I)",
                    "Rpim(I+/-)",
                    "Partial Bias",
                ]
                stats = [k for k in keys if k in statistics_all[key]]

                xwavelength = xcrystal.get_xwavelength(dname)
                sweeps = xwavelength.get_sweeps()

                tmp["AutoProcScalingStatistics"] = []
                tmp2 = tmp["AutoProcScalingStatistics"]

                for j, name in enumerate(
                    ["overall", "innerShell", "outerShell"]):
                    statistics_cache = {"scalingStatisticsType": name}

                    for s in stats:

                        if s in self._name_map:
                            n = self._name_map[s]
                        else:
                            continue

                        if isinstance(statistics_all[key][s], type([])):
                            statistics_cache[n] = statistics_all[key][s][j]
                        elif isinstance(statistics_all[key][s], type(())):
                            statistics_cache[n] = statistics_all[key][s][j]

                    tmp2.append(statistics_cache)

                tmp["AutoProcIntegrationContainer"] = []
                tmp2 = tmp["AutoProcIntegrationContainer"]
                for sweep in sweeps:
                    if "#" in sweep.get_template():
                        image_name = sweep.get_image_name(0)
                    else:
                        image_name = os.path.join(sweep.get_directory(),
                                                  sweep.get_template())
                    cell = sweep.get_integrater_cell()
                    intgr_tmp = {}
                    for name, value in zip(
                        ["a", "b", "c", "alpha", "beta", "gamma"], cell):
                        intgr_tmp["cell_%s" % name] = value

                    # FIXME this is naughty
                    indxr = sweep._get_indexer()
                    intgr = sweep._get_integrater()

                    start, end = intgr.get_integrater_wedge()

                    intgr_tmp["startImageNumber"] = start
                    intgr_tmp["endImageNumber"] = end

                    intgr_tmp[
                        "refinedDetectorDistance"] = indxr.get_indexer_distance(
                        )

                    beam = indxr.get_indexer_beam_centre_raw_image()

                    intgr_tmp["refinedXBeam"] = beam[0]
                    intgr_tmp["refinedYBeam"] = beam[1]

                    tmp2.append({
                        "Image": {
                            "fileName": os.path.split(image_name)[-1],
                            "fileLocation":
                            sanitize(os.path.split(image_name)[0]),
                        },
                        "AutoProcIntegration": intgr_tmp,
                    })

            # file unpacking nonsense
            result["AutoProcProgramContainer"] = {}
            tmp = result["AutoProcProgramContainer"]
            tmp2 = {}

            if not command_line:
                from xia2.Handlers.CommandLine import CommandLine

                command_line = CommandLine.get_command_line()

            tmp2["processingCommandLine"] = sanitize(command_line)
            tmp2["processingProgram"] = "xia2"

            tmp["AutoProcProgram"] = tmp2
            tmp["AutoProcProgramAttachment"] = []
            tmp2 = tmp["AutoProcProgramAttachment"]

            data_directory = self._project.path / "DataFiles"

            for k in reflection_files:
                reflection_file = reflection_files[k]

                if not isinstance(reflection_file, type("")):
                    continue

                reflection_file = FileHandler.get_data_file(
                    self._project.path, reflection_file)
                basename = os.path.basename(reflection_file)

                if data_directory.joinpath(basename).exists():
                    # Use file in DataFiles directory in preference (if it exists)
                    reflection_file = str(data_directory.joinpath(basename))

                tmp2.append({
                    "fileType":
                    "Result",
                    "fileName":
                    os.path.split(reflection_file)[-1],
                    "filePath":
                    sanitize(os.path.split(reflection_file)[0]),
                })

            tmp2.append({
                "fileType": "Log",
                "fileName": "xia2.txt",
                "filePath": sanitize(os.getcwd()),
            })

        return result
Beispiel #9
0
    def write_xml(self, file, command_line="", working_phil=None):
        if working_phil is not None:
            PhilIndex.merge_phil(working_phil)
        params = PhilIndex.get_python_object()

        fout = open(file, "w")

        fout.write('<?xml version="1.0"?>')
        fout.write("<AutoProcContainer>\n")

        for crystal in sorted(self._crystals):
            xcrystal = self._crystals[crystal]

            cell = xcrystal.get_cell()
            spacegroup = xcrystal.get_likely_spacegroups()[0]

            fout.write("<AutoProc><spaceGroup>%s</spaceGroup>" % spacegroup)
            self.write_refined_cell(fout, cell)
            fout.write("</AutoProc>")

            fout.write("<AutoProcScalingContainer>")
            fout.write("<AutoProcScaling>")
            self.write_date(fout)
            fout.write("</AutoProcScaling>")

            statistics_all = xcrystal.get_statistics()
            reflection_files = xcrystal.get_scaled_merged_reflections()

            for key in statistics_all:
                pname, xname, dname = key

                # FIXME should assert that the dname is a
                # valid wavelength name

                keys = [
                    "High resolution limit",
                    "Low resolution limit",
                    "Completeness",
                    "Multiplicity",
                    "I/sigma",
                    "Rmerge(I+/-)",
                    "CC half",
                    "Anomalous completeness",
                    "Anomalous correlation",
                    "Anomalous multiplicity",
                    "Total observations",
                    "Total unique",
                    "Rmeas(I)",
                    "Rmeas(I+/-)",
                    "Rpim(I)",
                    "Rpim(I+/-)",
                    "Partial Bias",
                ]

                stats = [k for k in keys if k in statistics_all[key]]

                xwavelength = xcrystal.get_xwavelength(dname)
                sweeps = xwavelength.get_sweeps()

                for j, name in enumerate(
                    ["overall", "innerShell", "outerShell"]):
                    statistics_cache = {}

                    for s in stats:
                        if isinstance(statistics_all[key][s], type([])):
                            statistics_cache[s] = statistics_all[key][s][j]
                        elif isinstance(statistics_all[key][s], type(())):
                            statistics_cache[s] = statistics_all[key][s][j]

                    # send these to be written out
                    self.write_scaling_statistics(fout, name, statistics_cache)

                for sweep in sweeps:
                    fout.write("<AutoProcIntegrationContainer>\n")
                    if "#" in sweep.get_template():
                        image_name = sweep.get_image_name(0)
                    else:
                        image_name = os.path.join(sweep.get_directory(),
                                                  sweep.get_template())
                    fout.write("<Image><fileName>%s</fileName>" %
                               os.path.split(image_name)[-1])
                    fout.write("<fileLocation>%s</fileLocation></Image>" %
                               sanitize(os.path.split(image_name)[0]))
                    fout.write("<AutoProcIntegration>\n")
                    cell = sweep.get_integrater_cell()
                    self.write_cell(fout, cell)

                    # FIXME this is naughty
                    intgr = sweep._get_integrater()

                    start, end = intgr.get_integrater_wedge()

                    fout.write("<startImageNumber>%d</startImageNumber>" %
                               start)

                    fout.write("<endImageNumber>%d</endImageNumber>" % end)

                    # FIXME this is naughty
                    indxr = sweep._get_indexer()

                    fout.write(
                        "<refinedDetectorDistance>%f</refinedDetectorDistance>"
                        % indxr.get_indexer_distance())

                    beam = indxr.get_indexer_beam_centre_raw_image()

                    fout.write("<refinedXBeam>%f</refinedXBeam>" % beam[0])
                    fout.write("<refinedYBeam>%f</refinedYBeam>" % beam[1])

                    fout.write("</AutoProcIntegration>\n")
                    fout.write("</AutoProcIntegrationContainer>\n")

            fout.write("</AutoProcScalingContainer>")

            # file unpacking nonsense

            if not command_line:
                from xia2.Handlers.CommandLine import CommandLine

                command_line = CommandLine.get_command_line()

            pipeline = params.xia2.settings.pipeline
            fout.write("<AutoProcProgramContainer><AutoProcProgram>")
            fout.write("<processingCommandLine>%s</processingCommandLine>" %
                       sanitize(command_line))
            fout.write("<processingPrograms>xia2 %s</processingPrograms>" %
                       pipeline)
            fout.write("</AutoProcProgram>")

            data_directory = self._project.path / "DataFiles"
            log_directory = self._project.path / "LogFiles"

            for k in reflection_files:
                reflection_file = reflection_files[k]

                if not isinstance(reflection_file, type("")):
                    continue

                reflection_file = FileHandler.get_data_file(
                    self._project.path, reflection_file)

                basename = os.path.basename(reflection_file)
                if data_directory.joinpath(basename).exists():
                    # Use file in DataFiles directory in preference (if it exists)
                    reflection_file = str(data_directory.joinpath(basename))

                fout.write("<AutoProcProgramAttachment><fileType>Result")
                fout.write("</fileType><fileName>%s</fileName>" %
                           os.path.split(reflection_file)[-1])
                fout.write("<filePath>%s</filePath>" %
                           sanitize(os.path.split(reflection_file)[0]))
                fout.write("</AutoProcProgramAttachment>\n")

            g = log_directory.glob("*merging-statistics.json")
            for merging_stats_json in g:
                fout.write("<AutoProcProgramAttachment><fileType>Graph")
                fout.write("</fileType><fileName>%s</fileName>" %
                           os.path.split(str(merging_stats_json))[-1])
                fout.write("<filePath>%s</filePath>" %
                           sanitize(str(log_directory)))
                fout.write("</AutoProcProgramAttachment>\n")

            # add the xia2.txt file...

            fout.write("<AutoProcProgramAttachment><fileType>Log")
            fout.write("</fileType><fileName>xia2.txt</fileName>")
            fout.write("<filePath>%s</filePath>" % sanitize(os.getcwd()))
            fout.write("</AutoProcProgramAttachment>\n")

            fout.write("</AutoProcProgramContainer>")

        fout.write("</AutoProcContainer>\n")
        fout.close()
Beispiel #10
0
  def write_xml(self, file):

    fout = open(file, 'w')

    fout.write('<?xml version="1.0"?>')
    fout.write('<AutoProcContainer>\n')

    for crystal in sorted(self._crystals):
      xcrystal = self._crystals[crystal]

      cell = xcrystal.get_cell()
      spacegroup = xcrystal.get_likely_spacegroups()[0]

      fout.write('<AutoProc><spaceGroup>%s</spaceGroup>' % spacegroup)
      self.write_refined_cell(fout, cell)
      fout.write('</AutoProc>')

      fout.write('<AutoProcScalingContainer>')
      fout.write('<AutoProcScaling>')
      self.write_date(fout)
      fout.write('</AutoProcScaling>')

      statistics_all = xcrystal.get_statistics()
      reflection_files = xcrystal.get_scaled_merged_reflections()

      wavelength_names = xcrystal.get_wavelength_names()

      for key in statistics_all.keys():
        pname, xname, dname = key

        # FIXME should assert that the dname is a
        # valid wavelength name

        available = statistics_all[key].keys()

        stats = []
        keys = [
            'High resolution limit',
            'Low resolution limit',
            'Completeness',
            'Multiplicity',
            'I/sigma',
            'Rmerge(I+/I-)',
            'CC half',
            'Anomalous completeness',
            'Anomalous correlation',
            'Anomalous multiplicity',
            'Total observations',
            'Total unique',
            'Rmeas(I)',
            'Rmeas(I+,-)',
            'Rpim(I)',
            'Rpim(I+/-)',
            'Partial Bias'
            ]

        for k in keys:
          if k in available:
            stats.append(k)

        xwavelength = xcrystal.get_xwavelength(dname)
        sweeps = xwavelength.get_sweeps()

        for j, name in enumerate(
            ['overall', 'innerShell', 'outerShell']):
          statistics_cache = { }

          for s in stats:
            if type(statistics_all[key][s]) == type([]):
              statistics_cache[s] = statistics_all[key][s][j]
            elif type(statistics_all[key][s]) == type(()):
              statistics_cache[s] = statistics_all[key][s][j]

          # send these to be written out
          self.write_scaling_statistics(fout, name,
                                        statistics_cache)

        for sweep in sweeps:
          fout.write('<AutoProcIntegrationContainer>\n')
          image_name = sweep.get_all_image_names()[0]
          fout.write('<Image><fileName>%s</fileName>' % \
                     os.path.split(image_name)[-1])
          fout.write('<fileLocation>%s</fileLocation></Image>' %
                     sanitize(os.path.split(image_name)[0]))
          fout.write('<AutoProcIntegration>\n')
          cell = sweep.get_integrater_cell()
          self.write_cell(fout, cell)

          # FIXME this is naughty
          intgr = sweep._get_integrater()

          start, end = intgr.get_integrater_wedge()

          fout.write('<startImageNumber>%d</startImageNumber>' % \
                     start)

          fout.write('<endImageNumber>%d</endImageNumber>' % \
                     end)

          # FIXME this is naughty
          indxr = sweep._get_indexer()

          fout.write(
              '<refinedDetectorDistance>%f</refinedDetectorDistance>' % \
              indxr.get_indexer_distance())

          beam = indxr.get_indexer_beam_centre()

          fout.write('<refinedXBeam>%f</refinedXBeam>' % beam[0])
          fout.write('<refinedYBeam>%f</refinedYBeam>' % beam[1])

          fout.write('</AutoProcIntegration>\n')
          fout.write('</AutoProcIntegrationContainer>\n')

      fout.write('</AutoProcScalingContainer>')

      # file unpacking nonsense

      from xia2.Handlers.CommandLine import CommandLine

      fout.write('<AutoProcProgramContainer><AutoProcProgram>')
      fout.write('<processingCommandLine>%s</processingCommandLine>' \
                 % sanitize(CommandLine.get_command_line()))
      fout.write('<processingPrograms>xia2</processingPrograms>')
      fout.write('</AutoProcProgram>')

      for k in reflection_files:

        reflection_file = reflection_files[k]

        if not type(reflection_file) == type(''):
          continue

        reflection_file = FileHandler.get_data_file(reflection_file)

        fout.write(
            '<AutoProcProgramAttachment><fileType>Result')
        fout.write('</fileType><fileName>%s</fileName>' % \
                   os.path.split(reflection_file)[-1])
        fout.write('<filePath>%s</filePath>' % \
                   sanitize(os.path.split(reflection_file)[0]))
        fout.write('</AutoProcProgramAttachment>\n')


      # add the xia2.txt file...

      fout.write('<AutoProcProgramAttachment><fileType>Log')
      fout.write('</fileType><fileName>xia2.txt</fileName>')
      fout.write('<filePath>%s</filePath>' % sanitize(os.getcwd()))
      fout.write('</AutoProcProgramAttachment>\n')

      fout.write('</AutoProcProgramContainer>')

    fout.write('</AutoProcContainer>\n')
    fout.close()

    return
Beispiel #11
0
def _write_sweeps(sweeps, out):
    global latest_sequence
    _known_sweeps = sweeps

    sweeplist = sorted(_known_sweeps)
    sweeplist = _filter_aliased_hdf5_sweeps(sweeplist)
    assert sweeplist, "no sweeps found"

    # sort sweeplist based on epoch of first image of each sweep
    epochs = [
        _known_sweeps[sweep][0].get_imageset().get_scan().get_epochs()[0]
        for sweep in sweeplist
    ]

    if len(epochs) != len(set(epochs)):
        logger.debug(
            "Duplicate epochs found. Trying to correct epoch information.")
        cumulativedelta = 0.0
        for sweep in sweeplist:
            _known_sweeps[sweep][0].get_imageset().get_scan().set_epochs(
                _known_sweeps[sweep][0].get_imageset().get_scan().get_epochs()
                + cumulativedelta)
            # could change the image epoch information individually, but only
            # the information from the first image is used at this time.
            cumulativedelta += sum(
                _known_sweeps[sweep]
                [0].get_imageset().get_scan().get_exposure_times())
        epochs = [
            _known_sweeps[sweep][0].get_imageset().get_scan().get_epochs()[0]
            for sweep in sweeplist
        ]

        if len(epochs) != len(set(epochs)):
            logger.debug("Duplicate epoch information remains.")
        # This should only happen with incorrect exposure time information.

    sweeplist = [s for _, s in sorted(zip(epochs, sweeplist))]

    # analysis pass

    wavelengths = []

    settings = PhilIndex.get_python_object().xia2.settings
    wavelength_tolerance = settings.wavelength_tolerance
    min_images = settings.input.min_images
    min_oscillation_range = settings.input.min_oscillation_range

    for sweep in sweeplist:
        sweeps = _known_sweeps[sweep]

        # sort on exposure epoch followed by first image number
        sweeps = sorted(
            sweeps,
            key=lambda s: (
                s.get_imageset().get_scan().get_epochs()[0],
                s.get_images()[0],
            ),
        )
        for s in sweeps:
            if len(s.get_images()) < min_images:
                logger.debug("Rejecting sweep %s:" % s.get_template())
                logger.debug(
                    "  Not enough images (found %i, require at least %i)" %
                    (len(s.get_images()), min_images))
                continue

            oscillation_range = s.get_imageset().get_scan(
            ).get_oscillation_range()
            width = oscillation_range[1] - oscillation_range[0]
            if min_oscillation_range is not None and width < min_oscillation_range:
                logger.debug("Rejecting sweep %s:" % s.get_template())
                logger.debug(
                    "  Too narrow oscillation range (found %i, require at least %i)"
                    % (width, min_oscillation_range))
                continue

            wavelength = s.get_wavelength()

            if wavelength not in wavelengths:
                have_wavelength = False
                for w in wavelengths:
                    if abs(w - wavelength) < wavelength_tolerance:
                        have_wavelength = True
                        s.set_wavelength(w)
                if not have_wavelength:
                    wavelengths.append(wavelength)

    assert wavelengths, "No sweeps found matching criteria"

    wavelength_map = {}

    project = settings.project
    crystal = settings.crystal

    out.write("BEGIN PROJECT %s\n" % project)
    out.write("BEGIN CRYSTAL %s\n" % crystal)

    out.write("\n")

    # check to see if a user spacegroup has been assigned - if it has,
    # copy it in...

    if settings.space_group is not None:
        out.write("USER_SPACEGROUP %s\n" %
                  settings.space_group.type().lookup_symbol())
        out.write("\n")

    if settings.unit_cell is not None:
        out.write("USER_CELL %.2f %.2f %.2f %.2f %.2f %.2f\n" %
                  settings.unit_cell.parameters())
        out.write("\n")

    freer_file = PhilIndex.params.xia2.settings.scale.freer_file
    if freer_file is not None:
        out.write("FREER_FILE %s\n" %
                  PhilIndex.params.xia2.settings.scale.freer_file)
        out.write("\n")

    if latest_sequence:
        out.write("BEGIN AA_SEQUENCE\n")
        out.write("\n")
        for sequence_chunk in [
                latest_sequence[i:i + 60]
                for i in range(0, len(latest_sequence), 60)
        ]:
            out.write("%s\n" % sequence_chunk)
        out.write("\n")
        out.write("END AA_SEQUENCE\n")
        out.write("\n")

    if settings.input.atom:
        out.write("BEGIN HA_INFO\n")
        out.write("ATOM %s\n" % settings.input.atom.lower())
        out.write("END HA_INFO\n")
        out.write("\n")
    elif settings.input.anomalous:
        out.write("BEGIN HA_INFO\n")
        out.write("ATOM X\n")
        out.write("END HA_INFO\n")
        out.write("\n")

    for j, wavelength in enumerate(wavelengths):
        anomalous = settings.input.anomalous
        if settings.input.atom is not None:
            anomalous = True
        if len(wavelengths) == 1 and anomalous:
            name = "SAD"
        elif len(wavelengths) == 1:
            name = "NATIVE"
        else:
            name = "WAVE%d" % (j + 1)

        wavelength_map[wavelength] = name

        out.write("BEGIN WAVELENGTH %s\n" % name)

        dmin = PhilIndex.params.xia2.settings.resolution.d_min
        dmax = PhilIndex.params.xia2.settings.resolution.d_max

        if dmin and dmax:
            out.write(f"RESOLUTION {dmin:f} {dmax:f}\n")
        elif dmin:
            out.write("RESOLUTION %f\n" % dmin)

        out.write("WAVELENGTH %f\n" % wavelengths[j])

        out.write("END WAVELENGTH %s\n" % name)
        out.write("\n")

    j = 0
    for sweep in sweeplist:
        sweeps = _known_sweeps[sweep]

        # sort on exposure epoch followed by first image number
        sweeps = sorted(
            sweeps,
            key=lambda s: (
                s.get_imageset().get_scan().get_epochs()[0],
                s.get_images()[0],
            ),
        )

        for s in sweeps:
            # require at least n images to represent a sweep...
            if len(s.get_images()) < min_images:
                logger.debug("Rejecting sweep %s:" % s.get_template())
                logger.debug(
                    "  Not enough images (found %i, require at least %i)" %
                    (len(s.get_images()), min_images))
                continue

            oscillation_range = s.get_imageset().get_scan(
            ).get_oscillation_range()
            width = oscillation_range[1] - oscillation_range[0]
            if min_oscillation_range is not None and width < min_oscillation_range:
                logger.debug("Rejecting sweep %s:" % s.get_template())
                logger.debug(
                    "  Too narrow oscillation range (found %i, require at least %i)"
                    % (width, min_oscillation_range))
                continue

            key = os.path.join(s.get_directory(), s.get_template())
            if CommandLine.get_start_ends(key):
                start_ends = CommandLine.get_start_ends(key)
                start_good = (min(s.get_images()) <= start_ends[0][0] <= max(
                    s.get_images()))
                end_good = (min(s.get_images()) <= start_ends[0][1] <= max(
                    s.get_images()))
                if not all((start_good, end_good)):
                    logger.debug("Rejecting sweep %s:" % s.get_template())
                    if not start_good:
                        logger.debug(
                            "  Your specified start-point image lies outside the bounds of this sweep."
                        )
                    if not end_good:
                        logger.debug(
                            "  Your specified end-point image lies outside the bounds of this sweep."
                        )
                    logger.debug(
                        "  Your specified start and end points were %d & %d," %
                        start_ends[0])
                    logger.debug(
                        "  this sweep consists of images from %d to %d." %
                        (min(s.get_images()), max(s.get_images())))
                    logger.debug(
                        """  If there are missing images in your sweep, but you have selected valid
  start and end points within a contiguous range of images, you will see this
  message, even though all is well with your selection, because xia2 treats
  each contiguous image range as a separate sweep.""")
                    continue
            else:
                start_ends = [(min(s.get_images()), max(s.get_images()))]

            for start_end in start_ends:
                j += 1
                name = "SWEEP%d" % j

                out.write("BEGIN SWEEP %s\n" % name)

                if PhilIndex.params.xia2.settings.input.reverse_phi:
                    out.write("REVERSEPHI\n")

                out.write("WAVELENGTH %s\n" %
                          wavelength_map[s.get_wavelength()])

                out.write("DIRECTORY %s\n" % s.get_directory())
                imgset = s.get_imageset()
                out.write("IMAGE %s\n" % os.path.split(imgset.get_path(0))[-1])
                out.write("START_END %d %d\n" % start_end)

                # really don't need to store the epoch in the xinfo file
                # out.write('EPOCH %d\n' % int(s.get_collect()[0]))
                if not settings.trust_beam_centre:
                    PhilIndex.params.xia2.settings.interactive = False
                    PhilIndex.get_python_object()

                if settings.detector_distance is not None:
                    out.write("DISTANCE %.2f\n" % settings.detector_distance)

                out.write("END SWEEP %s\n" % name)

                out.write("\n")

    out.write("END CRYSTAL %s\n" % crystal)
    out.write("END PROJECT %s\n" % project)
Beispiel #12
0
def load_imagesets(
    template,
    directory,
    id_image=None,
    image_range=None,
    use_cache=True,
    reversephi=False,
):
    global imageset_cache
    from dxtbx.model.experiment_list import ExperimentListFactory
    from xia2.Applications.xia2setup import known_hdf5_extensions
    from dxtbx.imageset import ImageSequence

    full_template_path = os.path.join(directory, template)

    if full_template_path not in imageset_cache or not use_cache:

        from dxtbx.model.experiment_list import BeamComparison
        from dxtbx.model.experiment_list import DetectorComparison
        from dxtbx.model.experiment_list import GoniometerComparison

        params = PhilIndex.params.xia2.settings
        compare_beam = BeamComparison(
            wavelength_tolerance=params.input.tolerance.beam.wavelength,
            direction_tolerance=params.input.tolerance.beam.direction,
            polarization_normal_tolerance=params.input.tolerance.beam.
            polarization_normal,
            polarization_fraction_tolerance=params.input.tolerance.beam.
            polarization_fraction,
        )
        compare_detector = DetectorComparison(
            fast_axis_tolerance=params.input.tolerance.detector.fast_axis,
            slow_axis_tolerance=params.input.tolerance.detector.slow_axis,
            origin_tolerance=params.input.tolerance.detector.origin,
        )
        compare_goniometer = GoniometerComparison(
            rotation_axis_tolerance=params.input.tolerance.goniometer.
            rotation_axis,
            fixed_rotation_tolerance=params.input.tolerance.goniometer.
            fixed_rotation,
            setting_rotation_tolerance=params.input.tolerance.goniometer.
            setting_rotation,
        )
        scan_tolerance = params.input.tolerance.scan.oscillation

        # If diamond anvil cell data, always use dynamic shadowing
        high_pressure = PhilIndex.params.dials.high_pressure.correction
        format_kwargs = {
            "dynamic_shadowing": params.input.format.dynamic_shadowing
            or high_pressure,
            "multi_panel": params.input.format.multi_panel,
        }

        if os.path.splitext(full_template_path)[-1] in known_hdf5_extensions:
            # if we are passed the correct file, use this, else look for a master
            # file (i.e. something_master.h5)

            if os.path.exists(full_template_path) and os.path.isfile(
                    full_template_path):
                master_file = full_template_path
            else:
                g = glob.glob(os.path.join(directory, "*_master.h5"))
                master_file = None
                for p in g:
                    substr = longest_common_substring(template, p)
                    if substr:
                        if master_file is None or (len(substr) > len(
                                longest_common_substring(
                                    template, master_file))):
                            master_file = p

            if master_file is None:
                raise RuntimeError("Can't find master file for %s" %
                                   full_template_path)

            unhandled = []
            experiments = ExperimentListFactory.from_filenames(
                [master_file],
                verbose=False,
                unhandled=unhandled,
                compare_beam=compare_beam,
                compare_detector=compare_detector,
                compare_goniometer=compare_goniometer,
                scan_tolerance=scan_tolerance,
                format_kwargs=format_kwargs,
            )

            assert len(unhandled) == 0, (
                "unhandled image files identified: %s" % unhandled)

        else:

            from dxtbx.sequence_filenames import locate_files_matching_template_string

            params = PhilIndex.get_python_object()
            read_all_image_headers = params.xia2.settings.read_all_image_headers

            if read_all_image_headers:
                paths = sorted(
                    locate_files_matching_template_string(full_template_path))
                unhandled = []
                experiments = ExperimentListFactory.from_filenames(
                    paths,
                    verbose=False,
                    unhandled=unhandled,
                    compare_beam=compare_beam,
                    compare_detector=compare_detector,
                    compare_goniometer=compare_goniometer,
                    scan_tolerance=scan_tolerance,
                    format_kwargs=format_kwargs,
                )
                assert len(unhandled) == 0, (
                    "unhandled image files identified: %s" % unhandled)

            else:
                from xia2.Handlers.CommandLine import CommandLine

                experiments = ExperimentList()
                start_ends = CommandLine.get_start_ends(full_template_path)
                if not start_ends:
                    start_ends.append(None)
                for start_end in start_ends:
                    importer = ExperimentListTemplateImporter(
                        [full_template_path],
                        format_kwargs=format_kwargs,
                        image_range=start_end,
                    )
                    experiments.extend(importer.experiments)

        imagesets = [
            iset for iset in experiments.imagesets()
            if isinstance(iset, ImageSequence)
        ]
        assert len(imagesets) > 0, "no imageset found"

        imageset_cache[full_template_path] = collections.OrderedDict()
        if reversephi:
            for imageset in imagesets:
                goniometer = imageset.get_goniometer()
                goniometer.set_rotation_axis(
                    tuple(-g for g in goniometer.get_rotation_axis()))

        reference_geometry = PhilIndex.params.xia2.settings.input.reference_geometry
        if reference_geometry is not None and len(reference_geometry) > 0:
            update_with_reference_geometry(imagesets, reference_geometry)

        # Update the geometry
        params = PhilIndex.params.xia2.settings
        update_geometry = []

        from dials.command_line.dials_import import ManualGeometryUpdater
        from dials.util.options import geometry_phil_scope

        # Then add manual geometry
        work_phil = geometry_phil_scope.format(params.input)
        diff_phil = geometry_phil_scope.fetch_diff(source=work_phil)
        if diff_phil.as_str() != "":
            update_geometry.append(ManualGeometryUpdater(params.input))

        imageset_list = []
        for imageset in imagesets:
            for updater in update_geometry:
                imageset = updater(imageset)
            imageset_list.append(imageset)
        imagesets = imageset_list

        for imageset in imagesets:
            scan = imageset.get_scan()
            exposure_times = scan.get_exposure_times()
            epochs = scan.get_epochs()
            if exposure_times.all_eq(0) or exposure_times[0] == 0:
                exposure_times = flex.double(exposure_times.size(), 1)
                scan.set_exposure_times(exposure_times)
            elif not exposure_times.all_gt(0):
                exposure_times = flex.double(exposure_times.size(),
                                             exposure_times[0])
                scan.set_exposure_times(exposure_times)
            if epochs.size() > 1 and not epochs.all_gt(0):
                if epochs[0] == 0:
                    epochs[0] = 1
                for i in range(1, epochs.size()):
                    epochs[i] = epochs[i - 1] + exposure_times[i - 1]
                scan.set_epochs(epochs)
            _id_image = scan.get_image_range()[0]
            imageset_cache[full_template_path][_id_image] = imageset

    if id_image is not None:
        return [imageset_cache[full_template_path][id_image]]
    elif image_range is not None:
        for imageset in imageset_cache[full_template_path].values():
            scan = imageset.get_scan()
            scan_image_range = scan.get_image_range()
            if (image_range[0] >= scan_image_range[0]
                    and image_range[1] <= scan_image_range[1]):
                b0 = scan.get_batch_offset()
                i0 = image_range[0] - scan_image_range[0] + b0
                i1 = image_range[1] - scan_image_range[0] + b0
                imagesets = [imageset[i0:i1 + 1]]
                assert len(
                    imagesets[0]) == image_range[1] - image_range[0] + 1, len(
                        imagesets[0])
                return imagesets
    return list(imageset_cache[full_template_path].values())