示例#1
0
def run(cbf_files, params):
    print "Attention - assuming cbf files given belong to a single dataset"
    print
    print "%d cbf files were given." % len(cbf_files)
    print

    if params.byteoffset:
        import yamtbx_byteoffset_h5_ext
        import pyublas

    last_shape = easy_mp.pool_map(fixed_func=lambda x: convert(x, params),
                                  args=cbf_files,
                                  processes=params.nproc)[-1]

    if params.decompose:
        make_geom_decomposed(
            XIO.Image(cbf_files[0]).header, last_shape, params.geom_out)
    else:
        make_geom(XIO.Image(cbf_files[0]).header, params.geom_out)

    make_beam(params.beam_out)

    print "Done."
    print
    print "Check %s and %s!" % (params.geom_out, params.beam_out)
示例#2
0
def takeout_datasets(img_template, min_frame, max_frame, _epsilon=1e-5,
                     check_wavelength=True, check_distance=True, check_oscwidth=True):
    img_indexes = []
    wavelengths = []
    distances   = []
    start_angles = []
    end_angles  = []
    ang_widths = []
    filenames = []

    img_files = template_to_filenames(img_template, min_frame, max_frame)

    # Read header
    for i, f in enumerate(img_files):
        if os.path.isfile(f):
            try:
                im = XIO.Image(f)
            except Exception, ex:
                print "Error on reading", f
                print traceback.format_exc()
                return []

            start_angles.append( im.header["PhiStart"] )
            end_angles.append( im.header["PhiEnd"] )
            ang_widths.append( im.header["PhiWidth"] )
            wavelengths.append( im.header["Wavelength"] )
            distances.append( im.header["Distance"] )
            img_indexes.append(min_frame+i)
            filenames.append(f)
示例#3
0
def is_dataset(img_template, min_frame, max_frame, _epsilon=1e-5, quiet=False):
    """
    Check whether image files belong to single dataset
     - Successive oscillation (missing frames OK)
     - Identical wavelength, distance
    """

    img_indexes = []
    wavelengths = []
    distances   = []
    start_angles = []
    end_angles  = []
    ang_widths = []
    filenames = []

    img_files = template_to_filenames(img_template, min_frame, max_frame)

    # Read header
    for i, f in enumerate(img_files):
        if os.path.isfile(f):
            try:
                im = XIO.Image(f)
            except Exception, ex:
                if not quiet:
                    print traceback.format_exc()
                return False

            start_angles.append( im.header["PhiStart"] )
            end_angles.append( im.header["PhiEnd"] )
            ang_widths.append( im.header["PhiWidth"] )
            wavelengths.append( im.header["Wavelength"] )
            distances.append( im.header["Distance"] )
            img_indexes.append(i+1)
            filenames.append(f)
示例#4
0
def convert(cbfin, params):
    if params.byteoffset:
        import yamtbx_byteoffset_h5_ext
        import pyublas

    h5out = os.path.basename(cbfin) + ".h5"

    data, ndimfast, ndimmid = cbf.load_minicbf_as_numpy(cbfin)
    data = data.reshape((ndimmid, ndimfast))
    if params.decompose:
        data = decompose_panels(data)
    header = XIO.Image(cbfin).header

    of = h5py.File(h5out, "w")

    grp = of.create_group("LCLS")
    dset = grp.create_dataset("photon_energy_eV", (1, ), dtype=numpy.float)
    dset[...] = 12398.4 / header["Wavelength"]
    dset = grp.create_dataset("photon_wavelength_A", (1, ), dtype=numpy.float)
    dset[...] = header["Wavelength"]
    dset = grp.create_dataset("adu_per_eV", (1, ), dtype=numpy.float)
    dset[...] = header["Wavelength"] / 12398.4
    dset = grp.create_dataset("detector_distance_m", (1, ), dtype=numpy.float)
    dset[...] = header["Distance"] / 1000.
    dset = grp.create_dataset("beam_xy_px", (2, ), dtype=numpy.float)
    dset[...] = (header["BeamX"] / header["PixelX"],
                 header["BeamY"] / header["PixelY"])
    dset = grp.create_dataset("osc_step_deg", (1, ), dtype=numpy.float)
    dset[...] = header["PhiWidth"]

    cbfin = os.path.abspath(cbfin)
    dset = grp.create_dataset("original_file", (1, ), "S%d" % len(cbfin))
    dset[...] = cbfin

    grp = of.create_group("data")
    if params.byteoffset:
        assert data.dtype == numpy.int32
        # hid_t group_id, const std::string &name, const pyublas::numpy_vector<int> &data, int width, int height)
        yamtbx_byteoffset_h5_ext.write_byteoffset_data(grp.id.id, "data",
                                                       data.ravel(),
                                                       data.shape[1],
                                                       data.shape[0])
    else:
        dset = grp.create_dataset("data", data.shape,
                                  dtype=data.dtype)  #, compression="CBF")
        dset[...] = data

    of.close()

    print "Processed: %s" % os.path.basename(cbfin)

    return data.shape
示例#5
0
def timestamps(img_files):
    img_date = []

    for f in img_files:
        im = XIO.Image(f)
        img_date.append((f, im.header["DateSeconds"]))

    for i in xrange(len(img_files)):
        print img_files[i],
        if i == 0:
            print 0
        else:
            print img_date[i][1] - img_date[i - 1][1]
示例#6
0
def find_data_sets(wdir, skip_symlinks=True, skip_0=False, split_hdf_miniset=True):
    """
    Find data sets in wdir
    """

    img_files = find_img_files(wdir, skip_symlinks=skip_symlinks)
    img_files.sort()

    h5files = filter(lambda x:x.endswith(".h5"), img_files)

    ret = []

    # group images
    group = group_img_files_template(img_files, skip_0=skip_0)
    print group

    for img_template, min_frame, max_frame in group:
        if min_frame == max_frame:
            continue

        for minf, maxf in takeout_datasets(img_template, min_frame, max_frame):
            ret.append([img_template, minf, maxf])

    for f in h5files:
        try:
            im = XIO.Image(f)
        except:
            print "Error on reading", f
            print traceback.format_exc()
            continue

        if not split_hdf_miniset:
            ret.append([f.replace("_master.h5","_??????.h5"), 1, im.header["Nimages"]])
            continue

        for i in xrange(im.header["Nimages"]//im.header["Nimages_each"]+1):
            nr0, nr1 = im.header["Nimages_each"]*i+1, im.header["Nimages_each"]*(i+1)
            if nr1 > im.header["Nimages"]: nr1 = im.header["Nimages"]
            ret.append([f.replace("_master.h5","_??????.h5"), nr0, nr1])
            if nr1 == im.header["Nimages"]: break

    return ret
示例#7
0
    def shorten_frame_range_if_missing(img_template, nr1, nr2):
        if "_??????.h5" in img_template:
            nr1 = max(nr1, 1)

            try:
                im = XIO.Image(img_template.replace("_??????.h5", "_master.h5"))
                nr2 = min(nr2, im.header["Nimages"])
            except:
                print "Error on reading", img_template
                print traceback.format_exc()
                nr1 = nr2 = 0
        else:
            files = glob.glob(img_template)
            if files:
                numbers = sorted(map(lambda x: int(x[img_template.index("?"):img_template.rindex("?")+1]), files))
                nr1 = max(nr1, numbers[0])
                nr2 = min(nr2, numbers[-1])
            else:
                nr1 = nr2 = 0
                
        return nr1, nr2
示例#8
0
def generate_xds_inp(img_files,
                     inp_dir,
                     reverse_phi,
                     anomalous,
                     spot_range=None,
                     minimum=False,
                     crystal_symmetry=None,
                     integrate_nimages=None,
                     osc_range=None,
                     orgx=None,
                     orgy=None,
                     rotation_axis=None,
                     distance=None,
                     wavelength=None,
                     minpk=None,
                     exclude_resolution_range=[],
                     fstart=None,
                     fend=None,
                     extra_kwds=[]):
    is_eiger_hdf5 = (len(img_files) == 1 and "_master.h5" in img_files[0])

    if is_eiger_hdf5:
        template = img_files[0].replace("_master.h5", "_??????.h5")
    else:
        groups = group_img_files_template(img_files)
        assert len(groups) == 1
        template, fstart, fend = groups[
            0]  # arguments fstart, fend are overwritten here
    #print inp_dir, img_files[0], template

    tmp = [
        os.path.dirname(os.path.relpath(img_files[0], inp_dir)),
        os.path.dirname(os.path.abspath(img_files[0]))
    ]
    imdir = min(tmp, key=lambda x: len(x))
    template = os.path.join(imdir, os.path.basename(template))
    #print imdir

    im = None
    for imgfile in img_files:
        if os.path.isfile(imgfile):
            im = XIO.Image(imgfile)
            break
    if im is None:
        raise Exception("No actual images found.")

    if crystal_symmetry is None:
        sgnum = 0
        cell_str = "50 60 70 90 90 90"
    else:
        sgnum = crystal_symmetry.space_group_info().type().number()
        cell_str = " ".join(
            map(lambda x: "%.2f" % x,
                crystal_symmetry.unit_cell().parameters()))

    if osc_range is None: osc_range = im.header["PhiWidth"]

    data_range = "%d %d" % (fstart, fend)
    if spot_range is None:
        spot_range = "%d %d" % (fstart, (fend + fstart) / 2)
    elif spot_range == "first":
        spot_range = "%d %d" % (fstart, fstart)
    elif spot_range == "all":
        spot_range = "%d %d" % (fstart, fend)
    elif len(spot_range) == 2:
        spot_range = "%d %d" % spot_range
    else:
        print "Error!"
        return

    if rotation_axis is None:
        if im.header["ImageType"] == "raxis": rotation_axis = (0, 1, 0)
        else: rotation_axis = (1, 0, 0)

    if reverse_phi: rotation_axis = map(lambda x: -1 * x, rotation_axis)
    rotation_axis = " ".join(map(lambda x: "%.2f" % x, rotation_axis))

    if integrate_nimages is None:
        delphi = 5
    else:
        delphi = osc_range * integrate_nimages

    nx, ny = im.header["Width"], im.header["Height"],
    qx, qy = im.header["PixelX"], im.header["PixelY"]
    if orgx is None: orgx = im.header["BeamX"] / qx
    if orgy is None: orgy = im.header["BeamY"] / qy
    if wavelength is None: wavelength = im.header["Wavelength"]
    if distance is None: distance = im.header["Distance"]
    friedel = "FALSE" if anomalous else "TRUE"
    sensor_thickness = 0  # FIXME

    if im.header["ImageType"] == "marccd":
        detector = "CCDCHESS MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65500"
    elif im.header["ImageType"] == "raxis":
        detector = "RAXIS MINIMUM_VALID_PIXEL_VALUE= 0  OVERLOAD= 2000000"
        distance *= -1
    elif im.header["ImageType"] == "minicbf":
        detector = "PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= 1048576"
        sensor_thickness = sensor_thickness_from_minicbf(img_files[0])
    elif im.header["ImageType"] == "adsc":
        detector = "ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
    elif im.header["ImageType"] == "mscccd":
        detector = "SATURN MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 262112"  # XXX Should read header!!
        distance *= -1
    elif is_eiger_hdf5:
        detector = "EIGER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= %d" % im.header[
            "Overload"]
        sensor_thickness = im.header["SensorThickness"]

    if minpk is not None: extra_kwds.append(" MINPK= %.2f" % minpk)
    for r1, r2 in exclude_resolution_range:
        if r1 < r2: r1, r2 = r2, r1
        extra_kwds.append(" EXCLUDE_RESOLUTION_RANGE= %.3f %.3f" % (r1, r2))

    extra_kwds = "\n".join(extra_kwds)
    inp_str = """\
 JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT
 ORGX= %(orgx).2f ORGY= %(orgy).2f
 DETECTOR_DISTANCE= %(distance).2f
 OSCILLATION_RANGE= %(osc_range).3f
 X-RAY_WAVELENGTH= %(wavelength).5f
 NAME_TEMPLATE_OF_DATA_FRAMES= %(template)s
! REFERENCE_DATA_SET=xxx/XDS_ASCII.HKL ! e.g. to ensure consistent indexing
 DATA_RANGE= %(data_range)s
 SPOT_RANGE= %(spot_range)s
! BACKGROUND_RANGE=1 10 ! rather use defaults (first 5 degree of rotation)
 FRIEDEL'S_LAW= %(friedel)s
 DELPHI= %(delphi).2f
! parameters specifically for this detector and beamline:
 DETECTOR= %(detector)s
 SENSOR_THICKNESS= %(sensor_thickness).2f
! attention CCD detectors: for very high resolution (better than 1A) make sure to specify SILICON
! as about 32* what CORRECT.LP suggests (absorption of phosphor is much higher than that of silicon)
 NX= %(nx)s NY= %(ny)s  QX= %(qx)s  QY= %(qy)s ! to make CORRECT happy if frames are unavailable
 ROTATION_AXIS= %(rotation_axis)s
%(extra_kwds)s
""" % locals()

    # XXX Really, really BAD idea!!
    # Synchrotron can have R-AXIS, and In-house detecotr can have horizontal goniometer..!!
    if im.header["ImageType"] == "raxis":
        inp_str += """\
 DIRECTION_OF_DETECTOR_X-AXIS= 1 0 0
 DIRECTION_OF_DETECTOR_Y-AXIS= 0 -1 0
 INCIDENT_BEAM_DIRECTION= 0 0 1
!FRACTION_OF_POLARIZATION= 0.98   ! uncomment if synchrotron
 POLARIZATION_PLANE_NORMAL= 1 0 0
"""
    else:
        if im.header["ImageType"] == "mscccd":
            inp_str += """\
 DIRECTION_OF_DETECTOR_X-AXIS= -1 0 0
 DIRECTION_OF_DETECTOR_Y-AXIS=  0 1 0
"""
        else:
            inp_str += """\
 DIRECTION_OF_DETECTOR_X-AXIS= 1 0 0
 DIRECTION_OF_DETECTOR_Y-AXIS= 0 1 0
"""
        inp_str += """\
 INCIDENT_BEAM_DIRECTION= 0 0 1
 FRACTION_OF_POLARIZATION= 0.98   ! better value is provided by beamline staff!
 POLARIZATION_PLANE_NORMAL= 0 1 0
"""

    if not minimum:
        inp_str += """\
 SPACE_GROUP_NUMBER= %(sgnum)d                   ! 0 if unknown
 UNIT_CELL_CONSTANTS= %(cell)s ! put correct values if known
 INCLUDE_RESOLUTION_RANGE=50 0  ! after CORRECT, insert high resol limit; re-run CORRECT

 TRUSTED_REGION=0.00 1.4  ! partially use corners of detectors; 1.41421=full use
 VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS=6000. 30000. ! often 7000 or 8000 is ok
 STRONG_PIXEL=4           ! COLSPOT: only use strong reflections (default is 3)
 MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=3 ! default of 6 is sometimes too high
! close spots: reduce SEPMIN and CLUSTER_RADIUS from their defaults of 6 and 3, e.g. to 4 and 2
! for bad or low resolution data remove the "!" in the following line:
 REFINE(IDXREF)=CELL BEAM ORIENTATION AXIS ! DISTANCE POSITION
 REFINE(INTEGRATE)= DISTANCE POSITION BEAM ORIENTATION ! AXIS CELL
! REFINE(CORRECT)=CELL BEAM ORIENTATION AXIS DISTANCE POSITION ! Default is: refine everything

!used by DEFPIX and CORRECT to exclude ice-reflections / ice rings - uncomment if necessary
!EXCLUDE_RESOLUTION_RANGE= 3.93 3.87 !ice-ring at 3.897 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.70 3.64 !ice-ring at 3.669 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.47 3.41 !ice-ring at 3.441 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 2.70 2.64 !ice-ring at 2.671 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 2.28 2.22 !ice-ring at 2.249 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 2.102 2.042 !ice-ring at 2.072 Angstrom - strong
!EXCLUDE_RESOLUTION_RANGE= 1.978 1.918 !ice-ring at 1.948 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.948 1.888 !ice-ring at 1.918 Angstrom - strong
!EXCLUDE_RESOLUTION_RANGE= 1.913 1.853 !ice-ring at 1.883 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.751 1.691 !ice-ring at 1.721 Angstrom - weak
""" % dict(sgnum=sgnum, cell=cell_str)
    if im.header["ImageType"] == "minicbf":
        inp_str += """\
 NUMBER_OF_PROFILE_GRID_POINTS_ALONG_ALPHA/BETA= 13 ! Default is 9 - Increasing may improve data
 NUMBER_OF_PROFILE_GRID_POINTS_ALONG_GAMMA= 13      ! accuracy, particularly if finely-sliced on phi,
!                                                   and does not seem to have any downsides.
"""
        if nx == 1475:
            if 1:  #! grep -q Flat_field tmp2: #XXX FIXME
                inp_str += """\
! the following specifications are for a detector _without_ proper
! flat_field correction; they cut away one additional pixel adjacent
! to each UNTRUSTED_RECTANGLE
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
 UNTRUSTED_RECTANGLE= 486  496     0 1680
 UNTRUSTED_RECTANGLE= 980  990     0 1680
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE PILATUS 2M DETECTOR
 UNTRUSTED_RECTANGLE=   0 1476   194  214
 UNTRUSTED_RECTANGLE=   0 1476   406  426
 UNTRUSTED_RECTANGLE=   0 1476   618  638
 UNTRUSTED_RECTANGLE=   0 1476   830  850
 UNTRUSTED_RECTANGLE=   0 1476  1042 1062
 UNTRUSTED_RECTANGLE=   0 1476  1254 1274
 UNTRUSTED_RECTANGLE=   0 1476  1466 1486
"""
            else:
                inp_str += """\
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
 UNTRUSTED_RECTANGLE= 487  495     0 1680
 UNTRUSTED_RECTANGLE= 981  989     0 1680
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE PILATUS 2M DETECTOR
 UNTRUSTED_RECTANGLE=   0 1476   195  213
 UNTRUSTED_RECTANGLE=   0 1476   407  425
 UNTRUSTED_RECTANGLE=   0 1476   619  637
 UNTRUSTED_RECTANGLE=   0 1476   831  849
 UNTRUSTED_RECTANGLE=   0 1476  1043 1061
 UNTRUSTED_RECTANGLE=   0 1476  1255 1273
 UNTRUSTED_RECTANGLE=   0 1476  1467 1485
"""

        elif nx == 2463:
            # Pilatus 6M
            # FIXME: here we could test if a Flat_field correction was applied like we do for 2M
            inp_str += """\
 UNTRUSTED_RECTANGLE= 487  495     0 2528
 UNTRUSTED_RECTANGLE= 981  989     0 2528
 UNTRUSTED_RECTANGLE=1475 1483     0 2528
 UNTRUSTED_RECTANGLE=1969 1977     0 2528
 UNTRUSTED_RECTANGLE=   0 2464   195  213
 UNTRUSTED_RECTANGLE=   0 2464   407  425
 UNTRUSTED_RECTANGLE=   0 2464   619  637
 UNTRUSTED_RECTANGLE=   0 2464   831  849
 UNTRUSTED_RECTANGLE=   0 2464  1043 1061
 UNTRUSTED_RECTANGLE=   0 2464  1255 1273
 UNTRUSTED_RECTANGLE=   0 2464  1467 1485
 UNTRUSTED_RECTANGLE=   0 2464  1679 1697
 UNTRUSTED_RECTANGLE=   0 2464  1891 1909
 UNTRUSTED_RECTANGLE=   0 2464  2103 2121
 UNTRUSTED_RECTANGLE=   0 2464  2315 2333
"""
    if is_eiger_hdf5 and nx == 3110 and ny == 3269:
        # Eiger 9M
        inp_str += """\
 UNTRUSTED_RECTANGLE= 1029 1042 0 3269
 UNTRUSTED_RECTANGLE= 2069 2082 0 3269
 UNTRUSTED_RECTANGLE= 0 3110  513  553
 UNTRUSTED_RECTANGLE= 0 3110 1064 1104
 UNTRUSTED_RECTANGLE= 0 3110 1615 1655
 UNTRUSTED_RECTANGLE= 0 3110 2166 2206
 UNTRUSTED_RECTANGLE= 0 3110 2717 2757
"""

    return inp_str
if __name__ == "__main__":
    import sys
    import optparse

    parser = optparse.OptionParser(usage="usage: %prog [options] img_files")
    parser.add_option(
        "--file-timestamp",
        "-f",
        action="store_true",
        dest="file_timestamp",
        help="Use file system time stamp instead of detector header")

    opts, args = parser.parse_args(sys.argv)

    img_date = []

    for f in args[1:]:
        if opts.file_timestamp:
            img_date.append((f, os.path.getmtime(f)))
        else:
            im = XIO.Image(f)
            img_date.append((f, im.header["DateSeconds"]))

    img_date.sort(key=lambda x: x[1])

    print "DateStr                    TimeDiff Filename"

    for i in xrange(len(img_date)):
        print time.ctime(img_date[i][1]),
        print "%10d %s" % (img_date[i][1] - img_date[0][1], img_date[i][0])
示例#10
0
def find_spots(img_file, params):
    """
    Use XDS to locate spots.
    If params.xds.do_defpix is true, DEFPIX will be run. For DEFPIX, dummy XPARM.XDS is needed. Thanks to DEFPIX, we can mask beam stop shadow and remove areas outside the resolution range.
    If false, we need to set TRUSTED_REGION to exclude regions outside resolution range, but it is independent of beam center. Maybe we should remove spots outside the resolution range after XDS run?
    """

    # Test if ramdisk available
    if os.path.isdir("/dev/shm"):
        work_dir = tempfile.mkdtemp(
            prefix="shika_x_" +
            os.path.splitext(os.path.basename(img_file))[0],
            dir="/dev/shm")
    else:
        work_dir = os.path.join(
            params.work_dir,
            "xds_" + os.path.splitext(os.path.basename(img_file))[0])

    xdsinp = os.path.join(work_dir, "XDS.INP")
    spot_xds = os.path.join(work_dir, "SPOT.XDS")

    if not os.path.exists(work_dir):
        os.mkdir(work_dir)

    template_str, min_frame, max_frame = dataset.group_img_files_template(
        [img_file])[0]

    im = XIO.Image(img_file)

    # Remove lines if None (means to use default)
    params_maps = [
        ("strong_pixel", "STRONG_PIXEL="),
        ("minimum_number_of_pixels_in_a_spot",
         "MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT="),
        ("background_pixel", "BACKGROUND_PIXEL="),
        ("maximum_number_of_strong_pixels",
         "MAXIMUM_NUMBER_OF_STRONG_PIXELS="),
        ("spot_maximum_centroid", "SPOT_MAXIMUM-CENTROID="),
        ("reflecting_range", "REFLECTING_RANGE="),
        ("value_range_for_trusted_detector_pixels",
         "VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS="),
    ]
    tmp = xds_inp_template.splitlines()
    for p, x in params_maps:
        if getattr(params.xds, p) is None:
            tmp = filter(lambda s: not s.startswith(x), tmp)
    inp_template = "\n".join(tmp)

    # Prepare XDS.INP
    inp_str = inp_template % dict(
        template=os.path.relpath(template_str, work_dir),
        framenum=min_frame,
        orgx=im.header["BeamX"] / im.header["PixelX"],
        orgy=im.header["BeamY"] / im.header["PixelY"],
        distance=im.header["Distance"],
        osc_range=im.header["PhiWidth"],
        wavelength=im.header["Wavelength"],
        strong_pixel=params.xds.strong_pixel,
        min_pixels=params.xds.minimum_number_of_pixels_in_a_spot,
        background_pixel=params.xds.background_pixel,
        max_strong_pixels=params.xds.maximum_number_of_strong_pixels,
        spot_maximum_centroid=params.xds.spot_maximum_centroid,
        reflecting_range=params.xds.reflecting_range,
        nx=im.header["Width"],
        ny=im.header["Height"],
        qx=im.header["PixelX"],
        qy=im.header["PixelY"],
        defpix_trusted1=params.xds.value_range_for_trusted_detector_pixels[0],
        defpix_trusted2=params.xds.value_range_for_trusted_detector_pixels[1])

    open(xdsinp, "w").write(inp_str)

    if params.xds.do_defpix:
        xp = xparm.XPARM()
        xp.set_info_from_xdsinp(xdsinp)
        open(os.path.join(work_dir, "XPARM.XDS"), "w").write(xp.xparm_str())
        modify_xdsinp(xdsinp,
                      inp_params=[("JOB", "XYCORR INIT DEFPIX"),
                                  ("INCLUDE_RESOLUTION_RANGE",
                                   res_range_for_xds(params.distl.res.outer,
                                                     params.distl.res.inner))])
        call("xds",
             wdir=work_dir,
             stdout=open(os.path.join(work_dir, "xds.log"), "w"))
        shutil.copy(os.path.join(work_dir, "BKGPIX.cbf"),
                    os.path.join(work_dir, "BKGINIT.cbf"))
        modify_xdsinp(xdsinp, inp_params=[("JOB", "COLSPOT")])
    else:
        modify_xdsinp(xdsinp,
                      inp_params=[
                          ("TRUSTED_REGION",
                           res_range_to_trusted_region(params.distl.res.outer,
                                                       params.distl.res.inner,
                                                       im.header))
                      ])
        open(os.path.join(work_dir, "xds.log"), "w").write("")

    # Run XDS
    rotate_file(spot_xds)
    call("xds",
         wdir=work_dir,
         stdout=open(os.path.join(work_dir, "xds.log"), "a"))

    # Extract results
    spots = []  # (x, y, d, intensity)
    if os.path.isfile(spot_xds):
        for l in open(spot_xds):
            x, y, z, intensity = map(lambda x: float(x), l.strip().split())
            d = coord_to_resol(x, y, im.header)
            spots.append((x, y, d, intensity))

    # Delete dir
    shutil.rmtree(work_dir)

    return spots
示例#11
0
def generate_xds_inp(img_files,
                     inp_dir,
                     use_dxtbx=False,
                     anomalous=True,
                     reverse_phi=None,
                     spot_range=None,
                     minimum=False,
                     crystal_symmetry=None,
                     integrate_nimages=None,
                     osc_range=None,
                     orgx=None,
                     orgy=None,
                     rotation_axis=None,
                     distance=None,
                     wavelength=None,
                     minpk=None,
                     exclude_resolution_range=None,
                     fstart=None,
                     fend=None,
                     extra_kwds=None,
                     overrides=None,
                     fix_geometry_when_overridden=False):
    """
    Reference: http://strucbio.biologie.uni-konstanz.de/xdswiki/index.php/Generate_XDS.INP
    """
    if not exclude_resolution_range: exclude_resolution_range = []
    if not extra_kwds: extra_kwds = []
    if not overrides: overrides = []

    is_eiger_hdf5 = (len(img_files) == 1 and "_master.h5" in img_files[0])

    if is_eiger_hdf5:
        template = img_files[0].replace("_master.h5", "_??????.h5")
    else:
        groups = group_img_files_template(img_files)
        assert len(groups) == 1
        template, fstart, fend = groups[
            0]  # arguments fstart, fend are overwritten here
    #print inp_dir, img_files[0], template

    tmp = [
        os.path.dirname(os.path.relpath(img_files[0], inp_dir)),
        os.path.dirname(os.path.abspath(img_files[0]))
    ]
    imdir = min(tmp, key=lambda x: len(x))
    template = os.path.join(imdir, os.path.basename(template))
    #print imdir

    if crystal_symmetry is None:
        sgnum = 0
        cell_str = "50 60 70 90 90 90"
    else:
        sgnum = crystal_symmetry.space_group_info().type().number()
        cell_str = " ".join(
            map(lambda x: "%.2f" % x,
                crystal_symmetry.unit_cell().parameters()))

    data_range = "%d %d" % (fstart, fend)
    if spot_range is None:
        spot_range = "%d %d" % (fstart, (fend + fstart) / 2)
    elif spot_range == "first":
        spot_range = "%d %d" % (fstart, fstart)
    elif spot_range == "all":
        spot_range = "%d %d" % (fstart, fend)
    elif len(spot_range) == 2:
        spot_range = "%d %d" % spot_range
    else:
        print "Error!"
        return

    friedel = "FALSE" if anomalous else "TRUE"
    is_pilatus_or_eiger = False

    img_files_existed = filter(lambda x: os.path.isfile(x), img_files)
    if not img_files_existed: raise Exception("No actual images found.")

    inp_str = """\
 MAXIMUM_NUMBER_OF_JOBS= 1
 JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT
 NAME_TEMPLATE_OF_DATA_FRAMES= %(template)s
 DATA_RANGE= %(data_range)s
 SPOT_RANGE= %(spot_range)s
!BACKGROUND_RANGE=1 10
 FRIEDEL'S_LAW= %(friedel)s
""" % locals()

    if use_dxtbx:
        # This is the current limitation..
        assert all(x is None for x in (osc_range, orgx, orgy, rotation_axis,
                                       distance, wavelength))

        toxds, inplst = read_geometry_using_dxtbx(img_files_existed[0])
        inp_str += "\n".join(inplst) + "\n"
        osc_range = toxds.oscillation_range
        nx, ny = toxds.detector_size
        is_pilatus_or_eiger = toxds.get_detector()[0].get_type(
        ) == "SENSOR_PAD"

    else:
        im = XIO.Image(img_files_existed[0])

        if osc_range is None: osc_range = im.header["PhiWidth"]

        if rotation_axis is None:  # automatic decision
            if "OscAxisVec" in im.header:
                rotation_axis = im.header["OscAxisVec"]
                print "DEBUG::rotation_axis from header:", rotation_axis
            else:
                if im.header["ImageType"] == "raxis": rotation_axis = (0, 1, 0)
                else: rotation_axis = (1, 0, 0)

                if reverse_phi is None:  # automatic decision
                    REVERSEPHI_SNs = dict(
                        marccd="""\
24
31
38
40
42
106
""".split(),  # Known detectors for reversed-phi in SPring-8: 24: BL26B2 Mar225, 31: BL32XU MX225HE, 38: BL44XU MX225HE, 42: BL44XU MX300HE, 40: BL41XU MX225HE, 106: BL32XU MX225HS
                        adsc="""\
915
458
924
""".split(),  # Known detectors for reversed-phi in SPring-8: 915: BL38B1 Q315; APS 19-ID: 458; BM30A: 924
                        minicbf="""\
PILATUS3 6M, S/N 60-0125
PILATUS3 6M, S/N 60-0132
PILATUS 2M, S/N 24-0109
""".splitlines(),  # Known detectors for reversed-phi in SPring-8: BL41XU PILATUS3 6M 60-0125, APS: 19ID PILATUS3 6M 60-0132, MX2 beamline (Brazilian Synchrotron National Laboratory - LNLS)
                    )
                    if im.header.get("SerialNumber") in REVERSEPHI_SNs.get(
                            im.header["ImageType"], ()):
                        print "DEBUG:: this is reversephi of", rotation_axis
                        reverse_phi = True

                if reverse_phi:
                    rotation_axis = map(lambda x: -1 * x, rotation_axis)

        rotation_axis = " ".join(map(lambda x: "%.6f" % x, rotation_axis))

        nx, ny = im.header["Width"], im.header["Height"],
        qx, qy = im.header["PixelX"], im.header["PixelY"]
        if orgx is None: orgx = im.header["BeamX"] / qx
        if orgy is None: orgy = im.header["BeamY"] / qy
        if wavelength is None: wavelength = im.header["Wavelength"]
        if distance is None: distance = im.header["Distance"]

        sensor_thickness = 0  # FIXME

        if im.header["ImageType"] == "marccd":
            detector = "CCDCHESS MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65500"
        elif im.header["ImageType"] == "raxis":
            detector = "RAXIS MINIMUM_VALID_PIXEL_VALUE= 0  OVERLOAD= 2000000"
            distance *= -1
        elif im.header["ImageType"] == "minicbf":
            detector = "PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= 1048576"
            sensor_thickness = sensor_thickness_from_minicbf(img_files[0])
            is_pilatus_or_eiger = True
        elif im.header["ImageType"] == "adsc":
            detector = "ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
        elif im.header["ImageType"] == "mscccd":
            detector = "SATURN MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 262112"  # XXX Should read header!!
            distance *= -1
        elif is_eiger_hdf5:
            detector = "EIGER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= %d" % im.header[
                "Overload"]
            sensor_thickness = im.header["SensorThickness"]
            is_pilatus_or_eiger = True

        inp_str += """\
 ORGX= %(orgx).2f ORGY= %(orgy).2f
 DETECTOR_DISTANCE= %(distance).2f
 OSCILLATION_RANGE= %(osc_range).3f
 X-RAY_WAVELENGTH= %(wavelength).5f
 DETECTOR= %(detector)s
 SENSOR_THICKNESS= %(sensor_thickness).2f
 NX= %(nx)s NY= %(ny)s  QX= %(qx)s  QY= %(qy)s
 ROTATION_AXIS= %(rotation_axis)s
 INCIDENT_BEAM_DIRECTION= 0 0 1
 FRACTION_OF_POLARIZATION= 0.98
 POLARIZATION_PLANE_NORMAL= 0 1 0
""" % locals()

        # XXX Synchrotron can have R-AXIS, and In-house detecotr can have horizontal goniometer!
        if im.header["ImageType"] == "raxis":
            inp_str += """\
 DIRECTION_OF_DETECTOR_X-AXIS= 1 0 0
 DIRECTION_OF_DETECTOR_Y-AXIS= 0 -1 0
 INCIDENT_BEAM_DIRECTION= 0 0 1
!FRACTION_OF_POLARIZATION= 0.98   ! uncomment if synchrotron
 POLARIZATION_PLANE_NORMAL= 1 0 0
"""
        else:
            if im.header["ImageType"] == "mscccd":
                inp_str += """\
 DIRECTION_OF_DETECTOR_X-AXIS= -1 0 0
 DIRECTION_OF_DETECTOR_Y-AXIS=  0 1 0
"""
            else:
                inp_str += """\
 DIRECTION_OF_DETECTOR_X-AXIS= 1 0 0
 DIRECTION_OF_DETECTOR_Y-AXIS= 0 1 0
"""

    if integrate_nimages is None:
        extra_kwds.append(" DELPHI= 5")
    else:
        extra_kwds.append(" DELPHI= %.4f" % osc_range * integrate_nimages)

    if minpk is not None: extra_kwds.append(" MINPK= %.2f" % minpk)
    for r1, r2 in exclude_resolution_range:
        if r1 < r2: r1, r2 = r2, r1
        extra_kwds.append(" EXCLUDE_RESOLUTION_RANGE= %.3f %.3f" % (r1, r2))

    extra_kwds = "\n".join(extra_kwds) + "\n"
    inp_str += extra_kwds

    if not minimum:
        inp_str += """\
 SPACE_GROUP_NUMBER= %(sgnum)d
 UNIT_CELL_CONSTANTS= %(cell)s
 INCLUDE_RESOLUTION_RANGE=50 0

 TRUSTED_REGION=0.00 1.4
 VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS=6000. 30000.
 STRONG_PIXEL=4
 MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=3
 REFINE(IDXREF)=CELL BEAM ORIENTATION AXIS ! DISTANCE POSITION
 REFINE(INTEGRATE)= DISTANCE POSITION BEAM ORIENTATION ! AXIS CELL
!REFINE(CORRECT)=CELL BEAM ORIENTATION AXIS DISTANCE POSITION
""" % dict(sgnum=sgnum, cell=cell_str)

    if is_pilatus_or_eiger:
        inp_str += """\
 NUMBER_OF_PROFILE_GRID_POINTS_ALONG_ALPHA/BETA= 13
 NUMBER_OF_PROFILE_GRID_POINTS_ALONG_GAMMA= 13
"""
        if nx == 1475 and ny == 1679:  # Pilatus 2M
            inp_str += """\
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
 UNTRUSTED_RECTANGLE= 486  496     0 1680
 UNTRUSTED_RECTANGLE= 980  990     0 1680
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE PILATUS 2M DETECTOR
 UNTRUSTED_RECTANGLE=   0 1476   194  214
 UNTRUSTED_RECTANGLE=   0 1476   406  426
 UNTRUSTED_RECTANGLE=   0 1476   618  638
 UNTRUSTED_RECTANGLE=   0 1476   830  850
 UNTRUSTED_RECTANGLE=   0 1476  1042 1062
 UNTRUSTED_RECTANGLE=   0 1476  1254 1274
 UNTRUSTED_RECTANGLE=   0 1476  1466 1486
"""
        elif nx == 2463 and ny == 2527:  # Pilatus 6M
            inp_str += """\
 UNTRUSTED_RECTANGLE= 487  495     0 2528
 UNTRUSTED_RECTANGLE= 981  989     0 2528
 UNTRUSTED_RECTANGLE=1475 1483     0 2528
 UNTRUSTED_RECTANGLE=1969 1977     0 2528
 UNTRUSTED_RECTANGLE=   0 2464   195  213
 UNTRUSTED_RECTANGLE=   0 2464   407  425
 UNTRUSTED_RECTANGLE=   0 2464   619  637
 UNTRUSTED_RECTANGLE=   0 2464   831  849
 UNTRUSTED_RECTANGLE=   0 2464  1043 1061
 UNTRUSTED_RECTANGLE=   0 2464  1255 1273
 UNTRUSTED_RECTANGLE=   0 2464  1467 1485
 UNTRUSTED_RECTANGLE=   0 2464  1679 1697
 UNTRUSTED_RECTANGLE=   0 2464  1891 1909
 UNTRUSTED_RECTANGLE=   0 2464  2103 2121
 UNTRUSTED_RECTANGLE=   0 2464  2315 2333
"""
        elif nx == 3110 and ny == 3269:  # Eiger 9M
            inp_str += """\
 UNTRUSTED_RECTANGLE= 1029 1042 0 3269
 UNTRUSTED_RECTANGLE= 2069 2082 0 3269
 UNTRUSTED_RECTANGLE= 0 3110  513  553
 UNTRUSTED_RECTANGLE= 0 3110 1064 1104
 UNTRUSTED_RECTANGLE= 0 3110 1615 1655
 UNTRUSTED_RECTANGLE= 0 3110 2166 2206
 UNTRUSTED_RECTANGLE= 0 3110 2717 2757
"""

    if overrides:
        inp_str += "\n! Overriding parameters:\n"
        inp_str += "\n".join(overrides) + "\n"

        if fix_geometry_when_overridden:
            inp_str += " REFINE(IDXREF)= CELL ORIENTATION ! BEAM AXIS DISTANCE POSITION\n"
            inp_str += " REFINE(INTEGRATE)= CELL ORIENTATION ! DISTANCE POSITION BEAM AXIS\n"

    return inp_str
示例#12
0
def run(cbfin):
    header = XIO.Image(cbfin).header
    make_geom(header, "pilatus.geom")