def test_grouped_observations():

    # some dummy observations for one reflection
    I1, I2, I3 = 101, 100, 99
    w1, w2, w3 = 0.9, 1.0, 0.8
    g1, g2, g3 = 1.01, 1.0, 0.99

    # combine with observations from some other group to make a dataset
    hkl = flex.miller_index([(0, 0, 1)] * 3 + [(0, 0, 2)] * 2)
    intensity = flex.double([I1, I2, I3, 10, 10])
    weight = flex.double([w1, w2, w3, 1.0, 1.0])
    phi = flex.double(len(hkl), 0)  # dummy
    scale = flex.double([g1, g2, g3, 1.0, 1.0])

    # group the observations by Miller index
    go = GroupedObservations(hkl, intensity, weight, phi, scale)

    # ensure there are two groups, the first of size 3, the second of size 2
    assert list(go.get_group_size()) == [3, 2]

    # the first group has an average intensity given by the HRS formula expanded:
    avI = (w1 * g1 * I1 + w2 * g2 * I2 +
           w3 * g3 * I3) / (w1 * g1 * g1 + w2 * g2 * g2 + w3 * g3 * g3)
    assert approx_equal(avI, go.get_average_intensity()[0])

    print "OK"
    def __init__(self, reflections, experiment, params=None):

        if params is None:
            params = om_scope.extract()

        # initial filter
        reflections = reflections.select(
            reflections.get_flags(reflections.flags.integrated)
        )

        # create new column containing the reduced Miller index
        xl = experiment.crystal
        symm = cctbx.crystal.symmetry(
            xl.get_unit_cell(), space_group=xl.get_space_group()
        )
        hkl_set = cctbx.miller.set(symm, reflections["miller_index"])
        asu_set = hkl_set.map_to_asu()
        reflections["asu_miller_index"] = asu_set.indices()

        # sort table by reduced hkl
        reflections.sort("asu_miller_index")

        if params.observations.integration_type == "mix":
            raise Sorry("integration_type=mix is not supported yet")
        else:
            ikey = "intensity." + params.observations.integration_type + ".value"
            vkey = "intensity." + params.observations.integration_type + ".variance"

        # filters
        sel = reflections[vkey] > 0
        reflections = reflections.select(sel)
        if params.observations.i_over_sigma_cutoff > 0:
            ios = reflections[ikey] / flex.sqrt(reflections[vkey])
            sel = ios >= params.observations.i_over_sigma_cutoff
            reflections = reflections.select(sel)
        if params.observations.min_multiplicity > 0:
            sel = minimum_multiplicity_selection(
                reflections["asu_miller_index"], params.observations.min_multiplicity
            )
            reflections = reflections.select(sel)

        # extract columns of interest
        gp_idx = reflections["asu_miller_index"]
        intensity = reflections[ikey]
        weight = 1.0 / reflections[vkey]
        phi = reflections["xyzcal.mm"].parts()[2]
        scale = flex.double(len(reflections), 1.0)

        # set up reflection grouping object
        self._go = GroupedObservations(gp_idx, intensity, weight, phi, scale)

        return