def __init__(SMG, goniometer):
                    from scitbx.array_family import flex
                    import math
                    SMG.goniometer = goniometer

                    coords = flex.vec3_double()
                    axis = flex.size_t()

                    # FACE A: Sample holder
                    #   Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis)
                    #   with rectangle of size a(A) = 12.8 mm (x 20 mm)

                    offsetA = 33.0
                    # semi-circle for phi=-90 ... +90
                    radiusA = 10.0
                    phi = flex.double_range(-90, 100, step=10) * math.pi / 180
                    x = flex.double(phi.size(), -offsetA)
                    y = radiusA * flex.cos(phi)
                    z = radiusA * flex.sin(phi)

                    # corners of square
                    sqdA = 12.8  # square depth
                    nsteps = 10
                    for i in range(nsteps + 1):
                        for sign in (+1, -1):
                            x.append(-offsetA)
                            y.append(i * -sqdA / nsteps)
                            z.append(sign * radiusA)
                    x.append(-offsetA)
                    y.append(-sqdA)
                    z.append(0)

                    SMG.faceA = flex.vec3_double(x, y, z)

                    # FACE B: Lower arm
                    sx = -28.50
                    sy = -4.90
                    sz = 8.50
                    mx = -13.80
                    my = -26.00
                    nx = -27.50
                    ny = -29.50
                    px = -65.50
                    py = -29.50
                    SMG.faceB = flex.vec3_double(
                        ((sx, sy, sz), (mx, my, 0), (nx, ny, 0), (px, py, 0)))

                    # FACE E: Rim of sample holder
                    #   Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an
                    #   offset o(E) = 19 mm

                    offsetE = 19.0
                    radiusE = 6.0
                    phi = flex.double_range(0, 360, step=15) * math.pi / 180
                    x = flex.double(phi.size(), -offsetE)
                    y = radiusE * flex.cos(phi)
                    z = radiusE * flex.sin(phi)

                    SMG.faceE = flex.vec3_double(x, y, z)
Beispiel #2
0
    def __init__(self, goniometer):
        # FACE A: Sample holder
        #   Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis)
        #   with rectangle of size a(A) = 12.8 mm (x 20 mm)

        offsetA = 33.0
        # semi-circle for phi=-90 ... +90
        radiusA = 10.0
        phi = flex.double_range(-90, 100, step=10) * math.pi / 180
        x = flex.double(phi.size(), -offsetA)
        y = radiusA * flex.cos(phi)
        z = radiusA * flex.sin(phi)

        # corners of square
        sqdA = 12.8  # square depth
        nsteps = 10
        for i in range(nsteps + 1):
            for sign in (+1, -1):
                x.append(-offsetA)
                y.append(i * -sqdA / nsteps)
                z.append(sign * radiusA)
        x.append(-offsetA)
        y.append(-sqdA)
        z.append(0)

        self.faceA = flex.vec3_double(-x, -y, z)

        # FACE B: Lower arm
        sx = -28.50
        sy = -4.90
        sz = 8.50
        mx = -13.80
        my = -26.00
        nx = -27.50
        ny = -29.50
        px = -65.50
        py = -29.50
        self.faceB = flex.vec3_double(
            ((-sx, -sy, sz), (-mx, -my, 0), (-nx, -ny, 0), (-px, -py, 0))
        )

        # FACE E: Rim of sample holder
        #   Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an
        #   offset o(E) = 19 mm

        offsetE = 19.0
        radiusE = 6.0
        phi = flex.double_range(0, 360, step=15) * math.pi / 180
        x = flex.double(phi.size(), -offsetE)
        y = radiusE * flex.cos(phi)
        z = radiusE * flex.sin(phi)

        self.faceE = flex.vec3_double(-x, -y, z)

        extrema_at_datum = self.faceA.deep_copy()
        extrema_at_datum.extend(self.faceE)
        super().__init__(
            goniometer, extrema_at_datum, flex.size_t(extrema_at_datum.size(), 1)
        )
        def __init__(self, goniometer):
            from scitbx.array_family import flex
            import math
            self.goniometer = goniometer

            coords = flex.vec3_double()
            axis = flex.size_t()

            # FACE A: Sample holder
            #   Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis)
            #   with rectangle of size a(A) = 12.8 mm (x 20 mm)

            offsetA = 33.0
            radiusA = 10.0
            sqdA = 12.8  # square depth
            phi = flex.double_range(-90, 100, step=10) * math.pi / 180
            x = flex.double(phi.size(), -offsetA)
            y = radiusA * flex.cos(phi)
            z = radiusA * flex.sin(phi)

            x.extend(flex.double(5, -offsetA))
            y.extend(flex.double((-sqdA / 2, -sqdA, -sqdA, -sqdA, -sqdA / 2)))
            z.extend(flex.double((radiusA, radiusA, 0, -radiusA, -radiusA)))

            self.faceA = flex.vec3_double(x, y, z)

            # FACE B: Lower arm
            sx = -28.50
            sy = -4.90
            sz = 8.50
            mx = -13.80
            my = -26.00
            nx = -27.50
            ny = -29.50
            px = -65.50
            py = -29.50
            self.faceB = flex.vec3_double(
                ((sx, sy, sz), (mx, my, 0), (nx, ny, 0), (px, py, 0)))

            # FACE E: Rim of sample holder
            #   Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an
            #   offset o(E) = 19 mm

            offsetE = 19.0
            radiusE = 6.0
            phi = flex.double_range(0, 360, step=15) * math.pi / 180
            x = flex.double(phi.size(), -offsetE)
            y = radiusE * flex.cos(phi)
            z = radiusE * flex.sin(phi)

            self.faceE = flex.vec3_double(x, y, z)
    def __init__(self, goniometer):
      from scitbx.array_family import flex
      import math
      self.goniometer = goniometer

      coords = flex.vec3_double()
      axis = flex.size_t()

      # FACE A: Sample holder
      #   Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis)
      #   with rectangle of size a(A) = 12.8 mm (x 20 mm)

      offsetA = 33.0
      radiusA = 10.0
      sqdA = 12.8 # square depth
      phi = flex.double_range(-90, 100, step=10) * math.pi/180
      x = flex.double(phi.size(), -offsetA)
      y = radiusA * flex.cos(phi)
      z = radiusA * flex.sin(phi)

      x.extend(flex.double(5, -offsetA))
      y.extend(flex.double((-sqdA/2, -sqdA, -sqdA, -sqdA, -sqdA/2)))
      z.extend(flex.double((radiusA, radiusA, 0, -radiusA, -radiusA)))

      self.faceA = flex.vec3_double(x, y, z)

      # FACE B: Lower arm
      sx = -28.50
      sy = -4.90
      sz = 8.50
      mx = -13.80
      my = -26.00
      nx = -27.50
      ny = -29.50
      px = -65.50
      py = -29.50
      self.faceB = flex.vec3_double(((sx,sy,sz),(mx,my,0),(nx,ny,0),(px,py,0)))

      # FACE E: Rim of sample holder
      #   Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an
      #   offset o(E) = 19 mm

      offsetE = 19.0
      radiusE = 6.0
      phi = flex.double_range(0, 360, step=15) * math.pi/180
      x = flex.double(phi.size(), -offsetE)
      y = radiusE * flex.cos(phi)
      z = radiusE * flex.sin(phi)

      self.faceE = flex.vec3_double(x, y, z)
Beispiel #5
0
    def get_goniometer_shadow_masker(self, goniometer=None):
        if goniometer is None:
            goniometer = self.get_goniometer()

        from dials.util.masking import GoniometerShadowMaskGenerator
        from scitbx.array_family import flex
        import math

        # Simple model of cone around goniometer phi axis
        # Exact values don't matter, only the ratio of height/radius
        height = 10  # mm

        cone_opening_angle = 2 * 38 * math.pi / 180
        radius_height_ratio = math.tan(1 / 2 * cone_opening_angle)
        radius = radius_height_ratio * height

        # print 2 * math.atan(radius/height) * 180 / math.pi

        steps_per_degree = 1
        theta = (flex.double([range(360 * steps_per_degree)]) * math.pi / 180 *
                 1 / steps_per_degree)
        x = radius * flex.cos(theta)  # x
        z = radius * flex.sin(theta)  # y
        y = flex.double(theta.size(), height)  # z

        coords = flex.vec3_double(zip(x, y, z))
        coords.extend(flex.vec3_double(zip(x, -y, z)))
        coords.insert(0, (0, 0, 0))

        if goniometer is None:
            goniometer = self.get_goniometer()
        return GoniometerShadowMaskGenerator(goniometer, coords,
                                             flex.size_t(len(coords), 0))
Beispiel #6
0
    def _construct_shadow_masker(goniometer):
        if request.param == "cpp":
            return GoniometerMaskerFactory.mini_kappa(goniometer)

        # Simple model of cone around goniometer phi axis
        # Exact values don't matter, only the ratio of height/radius
        height = 50  # mm
        radius = 20  # mm

        steps_per_degree = 1
        theta = (
            flex.double(range(360 * steps_per_degree))
            * math.pi
            / 180
            * 1
            / steps_per_degree
        )
        y = radius * flex.cos(-theta)
        z = radius * flex.sin(-theta)
        x = flex.double(theta.size(), height)

        coords = flex.vec3_double(zip(x, y, z))
        coords.insert(0, (0, 0, 0))

        return PyGoniometerShadowMasker(goniometer, coords, flex.size_t(len(coords), 0))
Beispiel #7
0
  def parts(self,fpp):
    dano_summation = None
    Ddanocalc_Dp = []
    for j,idx in enumerate(self.scatterer_idx):
      bool_array = self.xray_structure.by_index_selection([idx])
      xrs_atom = self.xray_structure.select(bool_array)
      #xrs_atom.show_scatterers()
      f_calc_atom = self.f_calc.structure_factors_from_scatterers(
        xray_structure=xrs_atom, algorithm=algorithm).f_calc()
      adata = f_calc_atom.data().parts()[0]
      bdata = f_calc_atom.data().parts()[1]

      product_factor = bdata * flex.cos(self.phases.data()) - adata * flex.sin(self.phases.data())
      # correspnds to -b cos(alpha) + a sin(alpha)
      #print list(xrs_atom.scattering_types())
      #xrs_atom.scattering_type_registry().show_summary()
      #xrs_atom.scattering_type_registry().show()
      f_zero = xrs_atom.scattering_type_registry().sum_of_scattering_factors_at_diffraction_angle_0()
      #print f_zero
      Ddanocalc_Dp.append((-2./f_zero)*product_factor)
      term = (-2.*fpp[j]/f_zero)*product_factor
      if dano_summation is None:
        dano_summation = term
      else:
        dano_summation += term
    return dano_summation,Ddanocalc_Dp


    """
Beispiel #8
0
    def parts(self, fpp):
        dano_summation = None
        Ddanocalc_Dp = []
        for j, idx in enumerate(self.scatterer_idx):
            bool_array = self.xray_structure.by_index_selection([idx])
            xrs_atom = self.xray_structure.select(bool_array)
            #xrs_atom.show_scatterers()
            f_calc_atom = self.f_calc.structure_factors_from_scatterers(
                xray_structure=xrs_atom, algorithm=algorithm).f_calc()
            adata = f_calc_atom.data().parts()[0]
            bdata = f_calc_atom.data().parts()[1]

            product_factor = bdata * flex.cos(
                self.phases.data()) - adata * flex.sin(self.phases.data())
            # correspnds to -b cos(alpha) + a sin(alpha)
            #print list(xrs_atom.scattering_types())
            #xrs_atom.scattering_type_registry().show_summary()
            #xrs_atom.scattering_type_registry().show()
            f_zero = xrs_atom.scattering_type_registry(
            ).sum_of_scattering_factors_at_diffraction_angle_0()
            #print f_zero
            Ddanocalc_Dp.append((-2. / f_zero) * product_factor)
            term = (-2. * fpp[j] / f_zero) * product_factor
            if dano_summation is None:
                dano_summation = term
            else:
                dano_summation += term
        return dano_summation, Ddanocalc_Dp
        """
Beispiel #9
0
def circ_mean(t, deg=True):
    assert (len(t) > 0)
    from scitbx.array_family import flex
    if (deg):
        t = math.pi * (t / 180)
    sx = flex.sum(flex.cos(t)) / len(t)
    sy = flex.sum(flex.sin(t)) / len(t)
    return math.degrees(math.atan2(sy, sx))
Beispiel #10
0
def circ_mean (t, deg=True) :
  assert (len(t) > 0)
  from scitbx.array_family import flex
  if (deg) :
    t = math.pi * (t/180)
  sx = flex.sum(flex.cos(t)) / len(t)
  sy = flex.sum(flex.sin(t)) / len(t)
  return math.degrees(math.atan2(sy, sx))
Beispiel #11
0
def circ_len (t, deg=True) :
  assert (len(t) > 0)
  from scitbx.array_family import flex
  if (deg) :
    t = math.pi * (t/180)
  sx = flex.sum(flex.cos(t)) / len(t)
  sy = flex.sum(flex.sin(t)) / len(t)
  return math.sqrt(sx**2 + sy**2)
Beispiel #12
0
def circ_len(t, deg=True):
    assert (len(t) > 0)
    from scitbx.array_family import flex
    if (deg):
        t = math.pi * (t / 180)
    sx = flex.sum(flex.cos(t)) / len(t)
    sy = flex.sum(flex.sin(t)) / len(t)
    return math.sqrt(sx**2 + sy**2)
 def __init__(self,working_phil):
     self.working_phil = working_phil
     self.two_theta_experimental = flex.double([
       1.5114,3.0160,4.5289,6.0422,7.5575,9.0733,10.5922,12.1106,13.6320,15.1563,16.6836,18.2107])
       # first 12 orders of silver behenate rings reported by Huang (1993) J Appl Cryst 26, 180-184.
     copper_Kalpha = 1.5418 # Angstroms
     d = flex.double(len(self.two_theta_experimental), copper_Kalpha/2.)
     self.experimental_d = d/flex.sin((math.pi/360.)*self.two_theta_experimental)
Beispiel #14
0
 def compute_functional_and_gradients(self, vector):
     assert len(vector) == 3
     two_pi_S_dot_v = 2 * math.pi * self.reciprocal_lattice_points.dot(vector)
     f = -flex.sum(flex.cos(two_pi_S_dot_v))
     sin_part = flex.sin(two_pi_S_dot_v)
     g = flex.double(
         [flex.sum(2 * math.pi * self._xyz_parts[i] * sin_part) for i in range(3)]
     )
     return f, g
Beispiel #15
0
 def __init__(self, working_phil):
     self.working_phil = working_phil
     self.two_theta_experimental = flex.double([
         1.5114, 3.0160, 4.5289, 6.0422, 7.5575, 9.0733, 10.5922, 12.1106,
         13.6320, 15.1563, 16.6836, 18.2107
     ])
     # first 12 orders of silver behenate rings reported by Huang (1993) J Appl Cryst 26, 180-184.
     copper_Kalpha = 1.5418  # Angstroms
     d = flex.double(len(self.two_theta_experimental), copper_Kalpha / 2.)
     self.experimental_d = d / flex.sin(
         (math.pi / 360.) * self.two_theta_experimental)
    def get_goniometer_shadow_masker(self, goniometer=None):
        if goniometer is None:
            goniometer = self.get_goniometer()

        assert goniometer is not None

        # avoid a module-level import from the DIALS namespace that kills LABELIT
        from dials.util.masking import GoniometerShadowMaskGenerator

        if goniometer.get_names()[1] == "GON_CHI":
            # SmarGon
            from dxtbx.format.SmarGonShadowMask import SmarGonShadowMaskGenerator

            return SmarGonShadowMaskGenerator(goniometer)

        elif goniometer.get_names()[1] == "GON_KAPPA":
            # mini Kappa

            from dials.util.masking import GoniometerShadowMaskGenerator
            from scitbx.array_family import flex

            # Simple model of cone around goniometer phi axis
            # Exact values don't matter, only the ratio of height/radius
            height = 50  # mm
            radius = 20  # mm

            steps_per_degree = 1
            theta = (
                flex.double([range(360 * steps_per_degree)])
                * math.pi
                / 180
                * 1
                / steps_per_degree
            )
            y = radius * flex.cos(theta)  # x
            z = radius * flex.sin(theta)  # y
            x = flex.double(theta.size(), height)  # z

            coords = flex.vec3_double(zip(x, y, z))
            coords.insert(0, (0, 0, 0))

            return GoniometerShadowMaskGenerator(
                goniometer, coords, flex.size_t(len(coords), 0)
            )

        else:
            raise RuntimeError(
                "Don't understand this goniometer: %s" % list(goniometer.get_names())
            )
    def diamond_anvil_cell(goniometer, cone_opening_angle):
        radius_height_ratio = math.tan(1 / 2 * cone_opening_angle)
        height = 10  # mm
        radius = radius_height_ratio * height

        steps_per_degree = 1
        theta = (flex.double([list(range(360 * steps_per_degree))]) * math.pi /
                 180 * 1 / steps_per_degree)
        x = radius * flex.cos(theta)  # x
        z = radius * flex.sin(theta)  # y
        y = flex.double(theta.size(), height)  # z

        coords = flex.vec3_double(zip(x, y, z))
        coords.extend(flex.vec3_double(zip(x, -y, z)))
        coords.insert(0, (0, 0, 0))

        return GoniometerShadowMasker(goniometer, coords,
                                      flex.size_t(len(coords), 0), True)
def tst_sphere():
    bli = intensity.block_integrator(50.0, 0.1, 1.0, 0.001)
    q = flex.double(range(1, 300)) / 1000.0
    bli.setup_arrays(q)
    r = flex.double(range(500)) / 500.0
    r = r
    pr = 6.0 * r * r * (2 - 3.0 * r + r * r * r)
    r = r * 50

    #for rr, pp in zip(r,pr):
    #  print rr, pp

    iii = bli.get_intensity(pr)
    iii = iii / 25.0

    jjj = (flex.sin(25.0 * q) -
           25.0 * q * flex.cos(q * 25.0)) / (1e-12 + q * q * q * 25 * 25 * 25)
    jjj = jjj * jjj
    jjj = jjj / jjj[0]
    for q, i, j in zip(q, iii, jjj):
        assert (abs(i - j) < 1e-2)
  def get_goniometer_shadow_masker(self, goniometer=None):
    from dials.util.masking import GoniometerShadowMaskGenerator
    from scitbx.array_family import flex
    import math

    # Simple model of cone around goniometer phi axis
    # Exact values don't matter, only the ratio of height/radius
    height = 50 # mm
    radius = 20 # mm

    steps_per_degree = 1
    theta = flex.double([range(360*steps_per_degree)]) * math.pi/180 * 1/steps_per_degree
    y = radius * flex.cos(theta) # x
    z = radius * flex.sin(theta) # y
    x = flex.double(theta.size(), height) # z

    coords = flex.vec3_double(zip(x, y, z))
    coords.insert(0, (0,0,0))

    if goniometer is None:
      goniometer = self.get_goniometer()
    return GoniometerShadowMaskGenerator(
      goniometer, coords, flex.size_t(len(coords), 0))
Beispiel #20
0
  def get_goniometer_shadow_masker(self, goniometer=None):
    from dials.util.masking import GoniometerShadowMaskGenerator
    from scitbx.array_family import flex
    import math

    # Simple model of cone around goniometer phi axis
    # Exact values don't matter, only the ratio of height/radius
    height = 50 # mm
    radius = 20 # mm

    steps_per_degree = 1
    theta = flex.double([range(360*steps_per_degree)]) * math.pi/180 * 1/steps_per_degree
    y = radius * flex.cos(theta) # x
    z = radius * flex.sin(theta) # y
    x = flex.double(theta.size(), height) # z

    coords = flex.vec3_double(zip(x, y, z))
    coords.insert(0, (0,0,0))

    if goniometer is None:
      goniometer = self.get_goniometer()
    return GoniometerShadowMaskGenerator(
      goniometer, coords, flex.size_t(len(coords), 0))
    def mini_kappa(goniometer, cone_opening_angle=43.60281897270362):
        """Construct a GoniometerShadowMasker for a mini-kappa goniometer.

        This is modelled a simple cone with the opening angle specified by
        `cone_opening_angle`.

        Args:
            goniometer (`dxtbx.model.Goniometer`): The goniometer instance.
            cone_opening_angle (float): The opening angle of the cone (in degrees).

        Returns:
            `dxtbx.masking.GoniometerShadowMasker`

        """
        assert isinstance(goniometer, MultiAxisGoniometer)
        assert len(goniometer.get_axes()) == 3
        # Simple model of cone around goniometer phi axis
        # Exact values don't matter, only the ratio of height/radius
        height = 50  # mm

        radius_height_ratio = math.tan(1 / 2 * cone_opening_angle * math.pi /
                                       180)
        radius = radius_height_ratio * height

        steps_per_degree = 1
        theta = (flex.double(range(360 * steps_per_degree)) * math.pi / 180 *
                 1 / steps_per_degree)
        y = radius * flex.cos(-theta)  # x
        z = radius * flex.sin(-theta)  # y
        x = flex.double(theta.size(), height)  # z

        coords = flex.vec3_double(zip(x, y, z))
        coords.insert(0, (0, 0, 0))

        return GoniometerShadowMasker(goniometer, coords,
                                      flex.size_t(len(coords), 0))
 def get_sinc(self, q, r):
     sinc = flex.sin(r * q) / (r * q)
     return sinc
Beispiel #23
0
def run(args, imageset=None):
    # Parse input
    try:
        len(args)
    except Exception:
        params = args
    else:
        user_phil = []
        for arg in args:
            if "=" in arg:
                try:
                    user_phil.append(libtbx.phil.parse(arg))
                except RuntimeError as e:
                    raise Sorry("Unrecognized argument '%s' (error: %s)" %
                                (arg, str(e)))
            else:
                try:
                    user_phil.append(
                        libtbx.phil.parse("""file_path=%s""" % arg))
                except ValueError:
                    raise Sorry("Unrecognized argument '%s'" % arg)
        params = master_phil.fetch(sources=user_phil).extract()
    if imageset is None:
        if (params.file_path is None or len(params.file_path) == 0
                or not all(os.path.isfile(f) for f in params.file_path)):
            master_phil.show()
            raise Usage(
                "file_path must be defined (either file_path=XXX, or the path alone)."
            )
    assert params.n_bins is not None
    assert params.verbose is not None
    assert params.output_bins is not None

    # Allow writing to a file instead of stdout
    if params.output_file is None:
        logger = sys.stdout
    else:
        logger = open(params.output_file, "w")
        logger.write("%s " % params.output_file)

    if params.show_plots:
        from matplotlib import pyplot as plt

        colormap = plt.cm.gist_ncar
        plt.gca().set_color_cycle(
            [colormap(i) for i in np.linspace(0, 0.9, len(params.file_path))])

    if params.mask is not None:
        params.mask = easy_pickle.load(params.mask)

    if imageset is None:
        iterable = params.file_path

        def load_func(x):
            try:
                obj = dxtbx.datablock.DataBlockFactory.from_filenames(
                    [x])[0].extract_imagesets()[0]
            except IndexError:
                try:
                    obj = dxtbx.datablock.DataBlockFactory.from_json_file(
                        x)[0].extract_imagesets()[0]
                except dxtbx.datablock.InvalidDataBlockError:
                    obj = ExperimentListFactory.from_json_file(x)[0].imageset
            return obj

    else:
        iterable = [imageset]

        def load_func(x):
            return x

    # Iterate over each file provided
    for item in iterable:
        iset = load_func(item)
        n_images = len(iset)
        if params.image_number is None:
            if params.max_images is None:
                subiterable = range(n_images)
            else:
                subiterable = range(0, min(params.max_images, n_images))
        else:
            subiterable = [params.image_number]
        for image_number in subiterable:
            beam = iset.get_beam(image_number)
            detector = iset.get_detector(image_number)
            s0 = col(beam.get_s0())

            # Search the detector for the panel farthest from the beam. The
            # number of bins in the radial average will be equal to the
            # farthest point from the beam on the detector, in pixels, unless
            # overridden at the command line
            panel_res = [p.get_max_resolution_at_corners(s0) for p in detector]
            farthest_panel = detector[panel_res.index(min(panel_res))]
            size2, size1 = farthest_panel.get_image_size()
            corners = [(0, 0), (size1 - 1, 0), (0, size2 - 1),
                       (size1 - 1, size2 - 1)]
            corners_lab = [
                col(farthest_panel.get_pixel_lab_coord(c)) for c in corners
            ]
            corner_two_thetas = [
                farthest_panel.get_two_theta_at_pixel(s0, c) for c in corners
            ]
            extent_two_theta = max(corner_two_thetas)
            max_corner = corners_lab[corner_two_thetas.index(extent_two_theta)]
            extent = int(
                math.ceil(max_corner.length() * math.sin(extent_two_theta) /
                          max(farthest_panel.get_pixel_size())))
            extent_two_theta *= 180 / math.pi

            if params.n_bins < extent:
                params.n_bins = extent

            # These arrays will store the radial average info
            sums = flex.double(params.n_bins) * 0
            sums_sq = flex.double(params.n_bins) * 0
            counts = flex.int(params.n_bins) * 0

            all_data = iset[image_number]

            if not isinstance(all_data, tuple):
                all_data = (all_data, )

            for tile, (panel, data) in enumerate(zip(detector, all_data)):
                if params.panel is not None and tile != params.panel:
                    continue

                if params.mask is None:
                    mask = flex.bool(flex.grid(data.focus()), True)
                else:
                    mask = params.mask[tile]

                if hasattr(data, "as_double"):
                    data = data.as_double()

                logger.flush()
                if params.verbose:
                    logger.write("Average intensity tile %d: %9.3f\n" %
                                 (tile, flex.mean(data)))
                    logger.write("N bins: %d\n" % params.n_bins)
                    logger.flush()

                x1, y1, x2, y2 = (
                    0,
                    0,
                    panel.get_image_size()[1],
                    panel.get_image_size()[0],
                )
                bc = panel.get_beam_centre_px(beam.get_s0())
                bc = int(round(bc[1])), int(round(bc[0]))

                # compute the average
                radial_average(
                    data,
                    mask,
                    bc,
                    sums,
                    sums_sq,
                    counts,
                    panel.get_pixel_size()[0],
                    panel.get_distance(),
                    (x1, y1),
                    (x2, y2),
                )

            # average the results, avoiding division by zero
            results = sums.set_selected(counts <= 0, 0)
            results /= counts.set_selected(counts <= 0, 1).as_double()

            if params.median_filter_size is not None:
                logger.write(
                    "WARNING, the median filter is not fully propagated to the variances\n"
                )
                from scipy.ndimage.filters import median_filter

                results = flex.double(
                    median_filter(results.as_numpy_array(),
                                  size=params.median_filter_size))

            # calculate standard devations
            stddev_sel = ((sums_sq - sums * results) >= 0) & (counts > 0)
            std_devs = flex.double(len(sums), 0)
            std_devs.set_selected(
                stddev_sel,
                (sums_sq.select(stddev_sel) -
                 sums.select(stddev_sel) * results.select(stddev_sel)) /
                counts.select(stddev_sel).as_double(),
            )
            std_devs = flex.sqrt(std_devs)

            twotheta = (flex.double(range(len(results))) * extent_two_theta /
                        params.n_bins)
            q_vals = (4 * math.pi * flex.sin(math.pi * twotheta / 360) /
                      beam.get_wavelength())
            # nlmbda = 2dsin(theta)
            resolution = flex.double(len(twotheta), 0)
            nonzero = twotheta > 0
            resolution.set_selected(
                nonzero,
                beam.get_wavelength() / (2 * flex.asin(
                    (math.pi / 180) * twotheta.select(nonzero) / 2)),
            )

            if params.low_max_two_theta_limit is None:
                subset = results
            else:
                subset = results.select(
                    twotheta >= params.low_max_two_theta_limit)

            max_result = flex.max(subset)

            if params.x_axis == "two_theta":
                xvals = twotheta
                max_x = twotheta[flex.first_index(results, max_result)]
            elif params.x_axis == "q":
                xvals = q_vals
                max_x = q_vals[flex.first_index(results, max_result)]
            elif params.x_axis == "resolution":
                xvals = resolution
                max_x = resolution[flex.first_index(results, max_result)]

            for i, r in enumerate(results):
                val = xvals[i]
                if params.output_bins and "%.3f" % r != "nan":
                    # logger.write("%9.3f %9.3f\n"%     (val,r))        #.xy  format for Rex.cell.
                    logger.write(
                        "%9.3f %9.3f %9.3f\n" %
                        (val, r, std_devs[i]))  # .xye format for GSASII
                # logger.write("%.3f %.3f %.3f\n"%(val,r,ds[i]))  # include calculated d spacings
            logger.write("Maximum %s: %f, value: %f\n" %
                         (params.x_axis, max_x, max_result))

            if params.show_plots:
                if params.plot_x_max is not None:
                    results = results.select(xvals <= params.plot_x_max)
                    xvals = xvals.select(xvals <= params.plot_x_max)
                if params.normalize:
                    plt.plot(
                        xvals.as_numpy_array(),
                        (results / flex.max(results)).as_numpy_array(),
                        "-",
                    )
                else:
                    plt.plot(xvals.as_numpy_array(), results.as_numpy_array(),
                             "-")
                if params.x_axis == "two_theta":
                    plt.xlabel("2 theta")
                elif params.x_axis == "q":
                    plt.xlabel("q")
                elif params.x_axis == "resolution":
                    plt.xlabel("Resolution ($\\AA$)")
                    plt.gca().set_xscale("log")
                    plt.gca().invert_xaxis()
                    plt.xlim(0, 50)
                plt.ylabel("Avg ADUs")
                if params.plot_y_max is not None:
                    plt.ylim(0, params.plot_y_max)

    if params.show_plots:
        # plt.legend([os.path.basename(os.path.splitext(f)[0]) for f in params.file_path], ncol=2)
        plt.show()

    return xvals, results
Beispiel #24
0
def background(imageset, indx, n_bins, mask_params=None):
    from dials.array_family import flex
    from libtbx.phil import parse
    from scitbx import matrix

    if mask_params is None:
        # Default mask params for trusted range
        mask_params = phil_scope.fetch(parse("")).extract().masking

    from dials.util.masking import MaskGenerator

    mask_generator = MaskGenerator(mask_params)
    mask = mask_generator.generate(imageset)

    detector = imageset.get_detector()
    beam = imageset.get_beam()
    # Only working with single panel detector for now
    assert len(detector) == 1
    panel = detector[0]
    mask = mask[0]

    n = matrix.col(panel.get_normal()).normalize()
    b = matrix.col(beam.get_s0()).normalize()
    wavelength = beam.get_wavelength()

    if math.fabs(b.dot(n)) < 0.95:
        raise Sorry("Detector not perpendicular to beam")

    data = imageset.get_raw_data(indx)
    assert len(data) == 1
    data = data[0]

    data = data.as_double()

    spot_params = spot_phil.fetch(source=parse("")).extract()
    threshold_function = SpotFinderFactory.configure_threshold(spot_params)
    peak_pixels = threshold_function.compute_threshold(data, mask)
    signal = data.select(peak_pixels.iselection())
    background_pixels = mask & ~peak_pixels
    background = data.select(background_pixels.iselection())

    # print some summary information
    print("Mean background: %.3f" % (flex.sum(background) / background.size()))
    if len(signal) > 0:
        print("Max/total signal pixels: %.0f / %.0f" %
              (flex.max(signal), flex.sum(signal)))
    else:
        print("No signal pixels on this image")
    print("Peak/background/masked pixels: %d / %d / %d" %
          (peak_pixels.count(True), background.size(), mask.count(False)))

    # compute histogram of two-theta values, then same weighted
    # by pixel values, finally divide latter by former to get
    # the radial profile out, need to set the number of bins
    # sensibly; inspired by method in PyFAI

    two_theta_array = panel.get_two_theta_array(beam.get_s0())
    two_theta_array = two_theta_array.as_1d().select(
        background_pixels.iselection())

    # Use flex.weighted_histogram
    h0 = flex.weighted_histogram(two_theta_array, n_slots=n_bins)
    h1 = flex.weighted_histogram(two_theta_array, background, n_slots=n_bins)
    h2 = flex.weighted_histogram(two_theta_array,
                                 background * background,
                                 n_slots=n_bins)

    d0 = h0.slots()
    d1 = h1.slots()
    d2 = h2.slots()

    I = d1 / d0
    I2 = d2 / d0
    sig = flex.sqrt(I2 - flex.pow2(I))

    tt = h0.slot_centers()
    d_spacings = wavelength / (2.0 * flex.sin(0.5 * tt))

    return d_spacings, I, sig
    def get_goniometer_shadow_masker(self, goniometer=None):
        if goniometer is None:
            goniometer = self.get_goniometer()

        assert goniometer is not None

        #avoid a module-level import from the DIALS namespace that kills LABELIT
        from dials.util.masking import GoniometerShadowMaskGenerator

        if goniometer.get_names()[1] == 'GON_CHI':
            # SmarGon

            class SmarGonShadowMaskGenerator(GoniometerShadowMaskGenerator):
                def __init__(SMG, goniometer):
                    from scitbx.array_family import flex
                    import math
                    SMG.goniometer = goniometer

                    coords = flex.vec3_double()
                    axis = flex.size_t()

                    # FACE A: Sample holder
                    #   Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis)
                    #   with rectangle of size a(A) = 12.8 mm (x 20 mm)

                    offsetA = 33.0
                    # semi-circle for phi=-90 ... +90
                    radiusA = 10.0
                    phi = flex.double_range(-90, 100, step=10) * math.pi / 180
                    x = flex.double(phi.size(), -offsetA)
                    y = radiusA * flex.cos(phi)
                    z = radiusA * flex.sin(phi)

                    # corners of square
                    sqdA = 12.8  # square depth
                    nsteps = 10
                    for i in range(nsteps + 1):
                        for sign in (+1, -1):
                            x.append(-offsetA)
                            y.append(i * -sqdA / nsteps)
                            z.append(sign * radiusA)
                    x.append(-offsetA)
                    y.append(-sqdA)
                    z.append(0)

                    SMG.faceA = flex.vec3_double(x, y, z)

                    # FACE B: Lower arm
                    sx = -28.50
                    sy = -4.90
                    sz = 8.50
                    mx = -13.80
                    my = -26.00
                    nx = -27.50
                    ny = -29.50
                    px = -65.50
                    py = -29.50
                    SMG.faceB = flex.vec3_double(
                        ((sx, sy, sz), (mx, my, 0), (nx, ny, 0), (px, py, 0)))

                    # FACE E: Rim of sample holder
                    #   Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an
                    #   offset o(E) = 19 mm

                    offsetE = 19.0
                    radiusE = 6.0
                    phi = flex.double_range(0, 360, step=15) * math.pi / 180
                    x = flex.double(phi.size(), -offsetE)
                    y = radiusE * flex.cos(phi)
                    z = radiusE * flex.sin(phi)

                    SMG.faceE = flex.vec3_double(x, y, z)

                def extrema_at_scan_angle(SMG, scan_angle):
                    from scitbx.array_family import flex

                    # Align end station coordinate system with ImgCIF coordinate system
                    from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame
                    from scitbx import matrix
                    R = align_reference_frame(matrix.col((-1, 0, 0)),
                                              matrix.col((1, 0, 0)),
                                              matrix.col((0, -1, 0)),
                                              matrix.col((0, 1, 0)))
                    faceA = R.elems * SMG.faceA
                    faceE = R.elems * SMG.faceE

                    axes = SMG.goniometer.get_axes()
                    angles = SMG.goniometer.get_angles()
                    scan_axis = SMG.goniometer.get_scan_axis()
                    angles[scan_axis] = scan_angle

                    extrema = flex.vec3_double()

                    for coords in (faceA, faceE):
                        coords = coords.deep_copy()
                        for i, axis in enumerate(axes):
                            if i == 0:
                                continue  # shadow doesn't change with phi setting
                            sel = flex.bool(len(coords), True)
                            rotation = matrix.col(
                                axis).axis_and_angle_as_r3_rotation_matrix(
                                    angles[i], deg=True)
                            coords.set_selected(
                                sel, rotation.elems * coords.select(sel))
                        extrema.extend(coords)

                    s = matrix.col(SMG.faceB[0])
                    mx, my, _ = SMG.faceB[1]
                    nx, ny, _ = SMG.faceB[2]
                    px, py, _ = SMG.faceB[3]

                    Rchi = (R.inverse() * matrix.col(axes[1])
                            ).axis_and_angle_as_r3_rotation_matrix(angles[1],
                                                                   deg=True)
                    sk = Rchi * s
                    sxk, syk, szk = sk.elems
                    coords = flex.vec3_double((
                        (sxk, syk, 0),
                        (sxk, syk, szk),
                        (sxk + mx / 2, syk + my / 2, szk),
                        (sxk + mx, syk + my, szk),
                        (sxk + (mx + nx) / 2, syk + (my + ny) / 2, szk),
                        (sxk + nx, syk + ny, szk),
                        (sxk + (nx + px) / 2, syk + (ny + py) / 2, szk),
                        (sxk + px, syk + py, szk),
                        (sxk + px, syk + py, 0),
                        (sxk + px, syk + py, -szk),
                        (sxk + (nx + px) / 2, syk + (ny + py) / 2, -szk),
                        (sxk + nx, syk + ny, -szk),
                        (sxk + (mx + nx) / 2, syk + (my + ny) / 2, -szk),
                        (sxk + mx, syk + my, -szk),
                        (sxk + mx / 2, syk + my / 2, -szk),
                        (sxk, syk, -szk),
                    ))

                    coords = R.elems * coords
                    Romega = matrix.col(
                        axes[2]).axis_and_angle_as_r3_rotation_matrix(
                            angles[2], deg=True)
                    coords = Romega.elems * coords
                    extrema.extend(coords)

                    return extrema

            #------------------ finished defining SmarGonShadowMaskGenerator
            return SmarGonShadowMaskGenerator(goniometer)

        elif goniometer.get_names()[1] == 'GON_KAPPA':
            # mini Kappa

            from dials.util.masking import GoniometerShadowMaskGenerator
            from scitbx.array_family import flex
            import math

            # Simple model of cone around goniometer phi axis
            # Exact values don't matter, only the ratio of height/radius
            height = 50  # mm
            radius = 20  # mm

            steps_per_degree = 1
            theta = flex.double([range(360 * steps_per_degree)
                                 ]) * math.pi / 180 * 1 / steps_per_degree
            y = radius * flex.cos(theta)  # x
            z = radius * flex.sin(theta)  # y
            x = flex.double(theta.size(), height)  # z

            coords = flex.vec3_double(zip(x, y, z))
            coords.insert(0, (0, 0, 0))

            if goniometer is None:
                goniometer = self.get_goniometer()
            return GoniometerShadowMaskGenerator(goniometer, coords,
                                                 flex.size_t(len(coords), 0))

        else:
            raise RuntimeError("Don't understand this goniometer: %s" %
                               list(goniometer.get_names()))
def sphere_data(q, d_max):
  r=d_max/2.0
  a = r*r*r*( flex.sin(q*r)-q*r*flex.cos(q*r) )/( r*r*r*q*q*q )
  return a*a
Beispiel #27
0
    def get_goniometer_shadow_masker(self, goniometer=None):
        from dials.util.masking import GoniometerShadowMaskGenerator
        from scitbx.array_family import flex
        import math

        coords = flex.vec3_double(((0, 0, 0), ))

        alpha = flex.double_range(0, 190, step=10) * math.pi / 180
        r = flex.double(alpha.size(), 40)
        x = flex.double(r.size(), 107.61)
        y = -r * flex.sin(alpha)
        z = -r * flex.cos(alpha)
        coords.extend(flex.vec3_double(x, y, z))

        coords.extend(
            flex.vec3_double((
                # fixed
                (107.49, 7.84, 39.49),
                (107.39, 15.69, 38.97),
                (107.27, 23.53, 38.46),
                (107.16, 31.37, 37.94),
                (101.76, 33.99, 36.25),
                (96.37, 36.63, 34.56),
                (90.98, 39.25, 33.00),
                (85.58, 41.88, 31.18),
                (80.89, 47.06, 31.00),
                (76.55, 51.51, 31.03),
                (72.90, 55.04, 31.18),
                (66.86, 60.46, 31.67),
                (62.10, 64.41, 32.25),
            )))

        alpha = flex.double_range(180, 370, step=10) * math.pi / 180
        r = flex.double(alpha.size(), 33)
        x = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) *
             flex.cos((50 * math.pi / 180) -
                      flex.atan(r / 89.02 * flex.sin(alpha))))
        y = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) *
             flex.sin((50 * math.pi / 180) -
                      flex.atan(r / 89.02 * flex.sin(alpha))))
        z = -r * flex.cos(alpha)
        coords.extend(flex.vec3_double(x, y, z))

        coords.extend(
            flex.vec3_double((
                # fixed
                (62.10, 64.41, -32.25),
                (66.86, 60.46, -31.67),
                (72.90, 55.04, -31.18),
                (76.55, 51.51, -31.03),
                (80.89, 47.06, -31.00),
                (85.58, 41.88, -31.18),
                (90.98, 39.25, -33.00),
                (96.37, 36.63, -34.56),
                (101.76, 33.99, -36.25),
                (107.16, 31.37, -37.94),
                (107.27, 23.53, -38.46),
                (107.39, 15.69, -38.97),
                (107.49, 7.84, -39.49),
                (107.61, 0.00, -40.00))))

        # I23 end station coordinate system:
        #   X-axis: positive direction is facing away from the storage ring (from
        #           sample towards goniometer)
        #   Y-axis: positive direction is vertically up
        #   Z-axis: positive direction is in the direction of the beam (from
        #           sample towards detector)
        #   K-axis (kappa): at an angle of +50 degrees from the X-axis
        #   K & phi rotation axes: clockwise rotation is positive (right hand
        #           thumb rule)
        #   Omega-axis: along the X-axis; clockwise rotation is positive

        # End station x-axis is parallel to ImgCIF x-axis
        # End station z-axis points in opposite direction to ImgCIF definition
        # (ImgCIF: The Z-axis is derived from the source axis which goes from
        # the sample to the source)
        # Consequently end station y-axis (to complete set following right hand
        # rule) points in opposite direction to ImgCIF y-axis.
        # Kappa arm aligned with -y in ImgCIF convention

        from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame
        from scitbx import matrix
        R = align_reference_frame(matrix.col((1, 0, 0)), matrix.col((1, 0, 0)),
                                  matrix.col((0, 1, 0)), matrix.col(
                                      (0, -1, 0)))
        coords = R.elems * coords

        if goniometer is None:
            goniometer = self.get_goniometer()
        return GoniometerShadowMaskGenerator(goniometer, coords,
                                             flex.size_t(len(coords), 1))
Beispiel #28
0
 def get_sinc(self, q, x):
     r = 0.5 * (x + 1) * self.d_max
     sinc = flex.sin(r * q) / (r * q)
     return sinc
def example():
    x_obs = (flex.double(range(100)) + 1.0) / 101.0
    y_ideal = flex.sin(x_obs * 6.0 * 3.1415) + flex.exp(x_obs)
    y_obs = y_ideal + (flex.random_double(size=x_obs.size()) - 0.5) * 0.5
    w_obs = flex.double(x_obs.size(), 1)
    print "Trying to determine the best number of terms "
    print " via cross validation techniques"
    print
    n_terms = chebyshev_lsq_fit.cross_validate_to_determine_number_of_terms(
        x_obs, y_obs, w_obs, min_terms=5, max_terms=20, n_goes=20, n_free=20)
    print "Fitting with", n_terms, "terms"
    print
    fit = chebyshev_lsq_fit.chebyshev_lsq_fit(n_terms, x_obs, y_obs)
    print "Least Squares residual: %7.6f" % (fit.f)
    print "  R2-value            : %7.6f" % (fit.f / flex.sum(y_obs * y_obs))
    print
    fit_funct = chebyshev_polynome(n_terms, fit.low_limit, fit.high_limit,
                                   fit.coefs)

    y_fitted = fit_funct.f(x_obs)
    abs_deviation = flex.max(flex.abs((y_ideal - y_fitted)))
    print "Maximum deviation between fitted and error free data:"
    print "    %4.3f" % (abs_deviation)
    abs_deviation = flex.mean(flex.abs((y_ideal - y_fitted)))
    print "Mean deviation between fitted and error free data:"
    print "    %4.3f" % (abs_deviation)
    print
    abs_deviation = flex.max(flex.abs((y_obs - y_fitted)))
    print "Maximum deviation between fitted and observed data:"
    print "    %4.3f" % (abs_deviation)
    abs_deviation = flex.mean(flex.abs((y_obs - y_fitted)))
    print "Mean deviation between fitted and observed data:"
    print "    %4.3f" % (abs_deviation)
    print
    print "Showing 10 points"
    print "   x    y_obs y_ideal y_fit"
    for ii in range(10):
        print "%6.3f %6.3f %6.3f %6.3f" \
              %(x_obs[ii*9], y_obs[ii*9], y_ideal[ii*9], y_fitted[ii*9])

    try:
        from iotbx import data_plots
    except ImportError:
        pass
    else:
        print "Preparing output for loggraph in a file called"
        print "   chebyshev.loggraph"
        chebyshev_plot = data_plots.plot_data(plot_title='Chebyshev fitting',
                                              x_label='x values',
                                              y_label='y values',
                                              x_data=x_obs,
                                              y_data=y_obs,
                                              y_legend='Observed y values',
                                              comments='Chebyshev fit')
        chebyshev_plot.add_data(y_data=y_ideal, y_legend='Error free y values')
        chebyshev_plot.add_data(y_data=y_fitted,
                                y_legend='Fitted chebyshev approximation')
        output_logfile = open('chebyshev.loggraph', 'w')
        f = StringIO()
        data_plots.plot_data_loggraph(chebyshev_plot, f)
        output_logfile.write(f.getvalue())
Beispiel #30
0
def background(imageset, indx, n_bins):
  from dials.array_family import flex
  from libtbx.phil import parse
  from scitbx import matrix
  import math

  detector = imageset.get_detector()
  beam = imageset.get_beam()
  assert(len(detector) == 1)
  detector = detector[0]
  trusted = detector.get_trusted_range()

  n = matrix.col(detector.get_normal()).normalize()
  b = matrix.col(beam.get_s0()).normalize()
  wavelength = beam.get_wavelength()

  if math.fabs(b.dot(n)) < 0.95:
    from libtbx.utils import Sorry
    raise Sorry('Detector not perpendicular to beam')

  data = imageset.get_raw_data(indx)
  assert(len(data) == 1)
  data = data[0]
  negative = (data < 0)
  hot = (data > int(round(trusted[1])))
  bad = negative | hot

  from dials.algorithms.spot_finding.factory import SpotFinderFactory
  from dials.algorithms.spot_finding.factory import phil_scope

  data = data.as_double()

  from dxtbx import datablock

  spot_params = phil_scope.fetch(source=parse("")).extract()
  threshold_function = SpotFinderFactory.configure_threshold(
    spot_params, datablock.DataBlock([imageset]))
  peak_pixels = threshold_function.compute_threshold(data, ~bad)
  signal = data.select(peak_pixels.iselection())
  background = data.select((~bad & ~peak_pixels).iselection())

  # print some summary information
  print('Mean background: %.3f' % (flex.sum(background) / background.size()))
  print('Max/total signal pixels: %.0f / %.0f' % (flex.max(signal),
                                                  flex.sum(signal)))
  print('Peak/background/hot pixels: %d / %d / %d' % (peak_pixels.count(True),
                                                      background.size(),
                                                      hot.count(True)))

  # compute histogram of two-theta values, then same weighted
  # by pixel values, finally divide latter by former to get
  # the radial profile out, need to set the number of bins
  # sensibly; flex.histogram does not allow weights so use
  # numpy.histogram to get the same effect... inspired by
  # method in PyFAI

  data = data.as_1d()
  two_theta_array = detector.get_two_theta_array(beam.get_s0())
  two_theta_array.set_selected((bad | peak_pixels).iselection(), 0.0)
  data.set_selected((bad | peak_pixels).iselection(), 0.0)

  # new fangled flex.weighted_histogram :-)
  h0 = flex.weighted_histogram(two_theta_array, n_slots=n_bins)
  h1 = flex.weighted_histogram(two_theta_array, data, n_slots=n_bins)
  h2 = flex.weighted_histogram(two_theta_array, data * data, n_slots=n_bins)

  d0 = h0.slots()
  d1 = h1.slots()
  d2 = h2.slots()

  I = d1 / d0
  I2 = d2 / d0
  sig = flex.sqrt(I2 - flex.pow2(I))

  tt = h0.slot_centers()
  d_spacings = wavelength / (2.0 * flex.sin(0.5 * tt))

  return d_spacings, I, sig
def example():
  x_obs = (flex.double(range(100))+1.0)/101.0
  y_ideal = flex.sin(x_obs*6.0*3.1415) + flex.exp(x_obs)
  y_obs = y_ideal + (flex.random_double(size=x_obs.size())-0.5)*0.5
  w_obs = flex.double(x_obs.size(),1)
  print "Trying to determine the best number of terms "
  print " via cross validation techniques"
  print
  n_terms = chebyshev_lsq_fit.cross_validate_to_determine_number_of_terms(
    x_obs,y_obs,w_obs,
    min_terms=5 ,max_terms=20,
    n_goes=20,n_free=20)
  print "Fitting with", n_terms, "terms"
  print
  fit = chebyshev_lsq_fit.chebyshev_lsq_fit(n_terms,x_obs,y_obs)
  print "Least Squares residual: %7.6f" %(fit.f)
  print "  R2-value            : %7.6f" %(fit.f/flex.sum(y_obs*y_obs))
  print
  fit_funct = chebyshev_polynome(
    n_terms, fit.low_limit, fit.high_limit, fit.coefs)

  y_fitted = fit_funct.f(x_obs)
  abs_deviation = flex.max(
    flex.abs( (y_ideal- y_fitted) ) )
  print "Maximum deviation between fitted and error free data:"
  print "    %4.3f" %(abs_deviation)
  abs_deviation = flex.mean(
    flex.abs( (y_ideal- y_fitted) ) )
  print "Mean deviation between fitted and error free data:"
  print "    %4.3f" %(abs_deviation)
  print
  abs_deviation = flex.max(
    flex.abs( (y_obs- y_fitted) ) )
  print "Maximum deviation between fitted and observed data:"
  print "    %4.3f" %(abs_deviation)
  abs_deviation = flex.mean(
    flex.abs( (y_obs- y_fitted) ) )
  print "Mean deviation between fitted and observed data:"
  print "    %4.3f" %(abs_deviation)
  print
  print "Showing 10 points"
  print "   x    y_obs y_ideal y_fit"
  for ii in range(10):
    print "%6.3f %6.3f %6.3f %6.3f" \
          %(x_obs[ii*9], y_obs[ii*9], y_ideal[ii*9], y_fitted[ii*9])

  try:
    from iotbx import data_plots
  except ImportError:
    pass
  else:
    print "Preparing output for loggraph in a file called"
    print "   chebyshev.loggraph"
    chebyshev_plot = data_plots.plot_data(plot_title='Chebyshev fitting',
                                          x_label = 'x values',
                                          y_label = 'y values',
                                          x_data = x_obs,
                                          y_data = y_obs,
                                          y_legend = 'Observed y values',
                                          comments = 'Chebyshev fit')
    chebyshev_plot.add_data(y_data=y_ideal,
                            y_legend='Error free y values')
    chebyshev_plot.add_data(y_data=y_fitted,
                            y_legend='Fitted chebyshev approximation')
    output_logfile=open('chebyshev.loggraph','w')
    f = StringIO()
    data_plots.plot_data_loggraph(chebyshev_plot,f)
    output_logfile.write(f.getvalue())
 def get_sinc(self, q, x ):
   r = 0.5*(x+1)*self.d_max
   sinc = flex.sin( r*q )/(r*q)
   return sinc
Beispiel #33
0
def background(imageset, indx, n_bins):
  from dials.array_family import flex
  from libtbx.phil import parse
  from scitbx import matrix
  import math

  detector = imageset.get_detector()
  beam = imageset.get_beam()
  assert(len(detector) == 1)
  detector = detector[0]
  trusted = detector.get_trusted_range()

  n = matrix.col(detector.get_normal()).normalize()
  b = matrix.col(beam.get_s0()).normalize()
  wavelength = beam.get_wavelength()

  if math.fabs(b.dot(n)) < 0.95:
    from libtbx.utils import Sorry
    raise Sorry('Detector not perpendicular to beam')

  data = imageset.get_raw_data(indx)
  assert(len(data) == 1)
  data = data[0]
  negative = (data < 0)
  hot = (data > int(round(trusted[1])))
  bad = negative | hot

  from dials.algorithms.spot_finding.factory import SpotFinderFactory
  from dials.algorithms.spot_finding.factory import phil_scope

  data = data.as_double()

  from dxtbx import datablock

  spot_params = phil_scope.fetch(source=parse("")).extract()
  threshold_function = SpotFinderFactory.configure_threshold(
    spot_params, datablock.DataBlock([imageset]))
  peak_pixels = threshold_function.compute_threshold(data, ~bad)
  signal = data.select(peak_pixels.iselection())
  background = data.select((~bad & ~peak_pixels).iselection())

  # print some summary information
  print 'Mean background: %.3f' % (flex.sum(background) / background.size())
  print 'Max/total signal pixels: %.0f / %.0f' % (flex.max(signal),
                                                 flex.sum(signal))
  print 'Peak/background/hot pixels: %d / %d / %d' % (peak_pixels.count(True),
                                                      background.size(),
                                                      hot.count(True))

  # compute histogram of two-theta values, then same weighted
  # by pixel values, finally divide latter by former to get
  # the radial profile out, need to set the number of bins
  # sensibly; flex.histogram does not allow weights so use
  # numpy.histogram to get the same effect... inspired by
  # method in PyFAI

  data = data.as_1d()
  two_theta_array = detector.get_two_theta_array(beam.get_s0())
  two_theta_array.set_selected((bad | peak_pixels).iselection(), 0.0)
  data.set_selected((bad | peak_pixels).iselection(), 0.0)

  # new fangled flex.weighted_histogram :-)
  h0 = flex.weighted_histogram(two_theta_array, n_slots=n_bins)
  h1 = flex.weighted_histogram(two_theta_array, data, n_slots=n_bins)
  h2 = flex.weighted_histogram(two_theta_array, data * data, n_slots=n_bins)

  d0 = h0.slots()
  d1 = h1.slots()
  d2 = h2.slots()

  I = d1 / d0
  I2 = d2 / d0
  sig = flex.sqrt(I2 - flex.pow2(I))

  tt = h0.slot_centers()
  d_spacings = wavelength / (2.0 * flex.sin(0.5 * tt))

  return d_spacings, I, sig
Beispiel #34
0
def run (args, image = None):
  from xfel import radial_average
  from scitbx.array_family import flex
  import os, sys
  import dxtbx

  # Parse input
  try:
    n = len(args)
  except Exception:
    params = args
  else:
    user_phil = []
    for arg in args:
      if (not "=" in arg):
        try :
          user_phil.append(libtbx.phil.parse("""file_path=%s""" % arg))
        except ValueError:
          raise Sorry("Unrecognized argument '%s'" % arg)
      else:
        try:
          user_phil.append(libtbx.phil.parse(arg))
        except RuntimeError as e:
          raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e)))
    params = master_phil.fetch(sources=user_phil).extract()
  if image is None:
    if params.file_path is None or len(params.file_path) == 0 or not all([os.path.isfile(f) for f in params.file_path]):
      master_phil.show()
      raise Usage("file_path must be defined (either file_path=XXX, or the path alone).")
  assert params.n_bins is not None
  assert params.verbose is not None
  assert params.output_bins is not None

  # Allow writing to a file instead of stdout
  if params.output_file is None:
    logger = sys.stdout
  else:
    logger = open(params.output_file, 'w')
    logger.write("%s "%params.output_file)

  if params.show_plots:
    from matplotlib import pyplot as plt
    import numpy as np
    colormap = plt.cm.gist_ncar
    plt.gca().set_color_cycle([colormap(i) for i in np.linspace(0, 0.9, len(params.file_path))])

  if params.mask is not None:
    params.mask = easy_pickle.load(params.mask)

  if image is None:
    iterable = params.file_path
    load_func = lambda x: dxtbx.load(x)
  else:
    iterable = [image]
    load_func = lambda x: x

  # Iterate over each file provided
  for item in iterable:
    img = load_func(item)
    try:
      n_images = img.get_num_images()
      subiterable = xrange(n_images)
    except AttributeError:
      n_images = None
      subiterable = [0]
    for image_number in subiterable:
      if n_images is None:
        beam = img.get_beam()
        detector = img.get_detector()
      else:
        beam = img.get_beam(image_number)
        detector = img.get_detector(image_number)
      s0 = col(beam.get_s0())

      # Search the detector for the panel farthest from the beam. The number of bins in the radial average will be
      # equal to the farthest point from the beam on the detector, in pixels, unless overridden at the command line
      panel_res = [p.get_max_resolution_at_corners(s0) for p in detector]
      farthest_panel = detector[panel_res.index(min(panel_res))]
      size2, size1 = farthest_panel.get_image_size()
      corners = [(0,0), (size1-1,0), (0,size2-1), (size1-1,size2-1)]
      corners_lab = [col(farthest_panel.get_pixel_lab_coord(c)) for c in corners]
      corner_two_thetas = [farthest_panel.get_two_theta_at_pixel(s0, c) for c in corners]
      extent_two_theta = max(corner_two_thetas)
      max_corner = corners_lab[corner_two_thetas.index(extent_two_theta)]
      extent = int(math.ceil(max_corner.length()*math.sin(extent_two_theta)/max(farthest_panel.get_pixel_size())))
      extent_two_theta *= 180/math.pi

      if params.n_bins < extent:
        params.n_bins = extent

      # These arrays will store the radial average info
      sums    = flex.double(params.n_bins) * 0
      sums_sq = flex.double(params.n_bins) * 0
      counts  = flex.int(params.n_bins) * 0

      if n_images is None:
        all_data = img.get_raw_data()
      else:
        all_data = img.get_raw_data(image_number)

      if not isinstance(all_data, tuple):
        all_data = (all_data,)

      for tile, (panel, data) in enumerate(zip(detector, all_data)):
        if params.mask is None:
          mask = flex.bool(flex.grid(data.focus()), True)
        else:
          mask = params.mask[tile]

        if hasattr(data,"as_double"):
          data = data.as_double()

        logger.flush()
        if params.verbose:
          logger.write("Average intensity tile %d: %9.3f\n"%(tile, flex.mean(data)))
          logger.write("N bins: %d\n"%params.n_bins)
          logger.flush()

        x1,y1,x2,y2 = 0,0,panel.get_image_size()[1],panel.get_image_size()[0]
        bc = panel.get_beam_centre_px(beam.get_s0())
        bc = int(round(bc[1])), int(round(bc[0]))

        # compute the average
        radial_average(data,mask,bc,sums,sums_sq,counts,panel.get_pixel_size()[0],panel.get_distance(),
                       (x1,y1),(x2,y2))

      # average the results, avoiding division by zero
      results = sums.set_selected(counts <= 0, 0)
      results /= counts.set_selected(counts <= 0, 1).as_double()

      if params.median_filter_size is not None:
        logger.write("WARNING, the median filter is not fully propogated to the variances\n")
        from scipy.ndimage.filters import median_filter
        results = flex.double(median_filter(results.as_numpy_array(), size = params.median_filter_size))

      # calculate standard devations
      stddev_sel = ((sums_sq-sums*results) >= 0) & (counts > 0)
      std_devs = flex.double(len(sums), 0)
      std_devs.set_selected(stddev_sel,
                           (sums_sq.select(stddev_sel)-sums.select(stddev_sel)* \
                            results.select(stddev_sel))/counts.select(stddev_sel).as_double())
      std_devs = flex.sqrt(std_devs)

      twotheta = flex.double(xrange(len(results)))*extent_two_theta/params.n_bins
      q_vals = 4*math.pi*flex.sin(math.pi*twotheta/360)/beam.get_wavelength()

      if params.low_max_two_theta_limit is None:
        subset = results
      else:
        subset = results.select(twotheta >= params.low_max_two_theta_limit)

      max_result = flex.max(subset)

      if params.x_axis == 'two_theta':
        xvals = twotheta
        max_x = twotheta[flex.first_index(results, max_result)]
      elif params.x_axis == 'q':
        xvals = q_vals
        max_x = q_vals[flex.first_index(results, max_result)]

      for i in xrange(len(results)):
        val = xvals[i]
        if params.output_bins and "%.3f"%results[i] != "nan":
         #logger.write("%9.3f %9.3f\n"%     (val,results[i]))        #.xy  format for Rex.cell.
          logger.write("%9.3f %9.3f %9.3f\n"%(val,results[i],std_devs[i])) #.xye format for GSASII
         #logger.write("%.3f %.3f %.3f\n"%(val,results[i],ds[i]))  # include calculated d spacings
      logger.write("Maximum %s: %f, value: %f\n"%(params.x_axis, max_x, max_result))

      if params.show_plots:
        if params.plot_x_max is not None:
          results = results.select(xvals <= params.plot_x_max)
          xvals = xvals.select(xvals <= params.plot_x_max)
        if params.normalize:
          plt.plot(xvals.as_numpy_array(),(results/flex.max(results)).as_numpy_array(),'-')
        else:
          plt.plot(xvals.as_numpy_array(),results.as_numpy_array(),'-')
        if params.x_axis == 'two_theta':
          plt.xlabel("2 theta")
        elif params.x_axis == 'q':
          plt.xlabel("q")
        plt.ylabel("Avg ADUs")
        if params.plot_y_max is not None:
          plt.ylim(0, params.plot_y_max)

    if params.show_plots:
      #plt.legend([os.path.basename(os.path.splitext(f)[0]) for f in params.file_path], ncol=2)
      plt.show()

  return xvals, results
  def get_goniometer_shadow_masker(self, goniometer=None):
    from dials.util.masking import GoniometerShadowMaskGenerator
    from scitbx.array_family import flex
    import math

    coords = flex.vec3_double((
      (0,0,0),
    ))

    alpha = flex.double_range(0, 190, step=10) * math.pi / 180
    r = flex.double(alpha.size(), 40)
    x = flex.double(r.size(), 107.61)
    y = -r*flex.sin(alpha)
    z = -r*flex.cos(alpha)
    coords.extend(flex.vec3_double(x, y, z))

    coords.extend(flex.vec3_double((
      # fixed
      (107.49, 7.84, 39.49),
      (107.39, 15.69, 38.97),
      (107.27, 23.53, 38.46),
      (107.16, 31.37, 37.94),
      (101.76, 33.99, 36.25),
      (96.37, 36.63, 34.56),
      (90.98, 39.25, 33.00),
      (85.58, 41.88, 31.18),
      (80.89, 47.06, 31.00),
      (76.55, 51.51, 31.03),
      (72.90, 55.04, 31.18),
      (66.86, 60.46, 31.67),
      (62.10, 64.41, 32.25),
    )))

    alpha = flex.double_range(180, 370, step=10) * math.pi / 180
    r = flex.double(alpha.size(), 33)
    x = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.cos((50 * math.pi/180) - flex.atan(r/89.02 * flex.sin(alpha))))
    y = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.sin((50 * math.pi/180) - flex.atan(r/89.02 * flex.sin(alpha))))
    z = -r*flex.cos(alpha)
    coords.extend(flex.vec3_double(x, y, z))

    coords.extend(flex.vec3_double((
      # fixed
      (62.10, 64.41, -32.25),
      (66.86, 60.46, -31.67),
      (72.90, 55.04, -31.18),
      (76.55, 51.51, -31.03),
      (80.89, 47.06, -31.00),
      (85.58, 41.88, -31.18),
      (90.98, 39.25, -33.00),
      (96.37, 36.63, -34.56),
      (101.76, 33.99, -36.25),
      (107.16, 31.37, -37.94),
      (107.27, 23.53, -38.46),
      (107.39, 15.69, -38.97),
      (107.49, 7.84, -39.49),
      (107.61, 0.00, -40.00)
    )))

    # I23 end station coordinate system:
    #   X-axis: positive direction is facing away from the storage ring (from
    #           sample towards goniometer)
    #   Y-axis: positive direction is vertically up
    #   Z-axis: positive direction is in the direction of the beam (from
    #           sample towards detector)
    #   K-axis (kappa): at an angle of +50 degrees from the X-axis
    #   K & phi rotation axes: clockwise rotation is positive (right hand
    #           thumb rule)
    #   Omega-axis: along the X-axis; clockwise rotation is positive

    # End station x-axis is parallel to ImgCIF x-axis
    # End station z-axis points in opposite direction to ImgCIF definition
    # (ImgCIF: The Z-axis is derived from the source axis which goes from
    # the sample to the source)
    # Consequently end station y-axis (to complete set following right hand
    # rule) points in opposite direction to ImgCIF y-axis.
    # Kappa arm aligned with -y in ImgCIF convention

    from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame
    from scitbx import matrix
    R = align_reference_frame(matrix.col((1,0,0)), matrix.col((1,0,0)),
                              matrix.col((0,1,0)), matrix.col((0,-1,0)))
    coords = R.elems * coords

    if goniometer is None:
      goniometer = self.get_goniometer()
    return GoniometerShadowMaskGenerator(
      goniometer, coords, flex.size_t(len(coords), 1))