<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def sample_cluster(sources, srcfilter, num_ses, param):
 """ Yields ruptures generated by a cluster of sources. :param sources: A sequence of sources of the same group :param num_ses: Number of stochastic event sets :param param: a dictionary of additional parameters including ses_per_logic_tree_path :yields: dictionaries with keys rup_array, calc_times, eff_ruptures """

    eb_ruptures = []
    numpy.random.seed(sources[0].serial)
    [grp_id] = set(src.src_group_id for src in sources)
    # AccumDict of arrays with 3 elements weight, nsites, calc_time
    calc_times = AccumDict(accum=numpy.zeros(3, numpy.float32))
    # Set the parameters required to compute the number of occurrences
    # of the group of sources
    #  assert param['oqparam'].number_of_logic_tree_samples > 0
    samples = getattr(sources[0], 'samples', 1)
    tom = getattr(sources, 'temporal_occurrence_model')
    rate = tom.occurrence_rate
    time_span = tom.time_span
    # Note that using a single time interval corresponding to the product
    # of the investigation time and the number of realisations as we do
    # here is admitted only in the case of a time-independent model
    grp_num_occ = numpy.random.poisson(rate * time_span * samples *
                                       num_ses)
    # Now we process the sources included in the group. Possible cases:
    # * The group is a cluster. In this case we choose one rupture per each
    #   source; uncertainty in the ruptures can be handled in this case
    #   using mutually exclusive ruptures (note that this is admitted
    #   only for nons-parametric sources).
    # * The group contains mutually exclusive sources. In this case we
    #   choose one source and then one rupture from this source.
    rup_counter = {}
    rup_data = {}
    eff_ruptures = 0
    for rlz_num in range(grp_num_occ):
        if sources.cluster:
            for src, _sites in srcfilter(sources):
                # Sum Ruptures
                if rlz_num == 0:
                    eff_ruptures += src.num_ruptures
                # Track calculation time
                t0 = time.time()
                rup = src.get_one_rupture()
                # The problem here is that we do not know a-priori the
                # number of occurrences of a given rupture.
                if src.id not in rup_counter:
                    rup_counter[src.id] = {}
                    rup_data[src.id] = {}
                if rup.idx not in rup_counter[src.id]:
                    rup_counter[src.id][rup.idx] = 1
                    rup_data[src.id][rup.idx] = [rup, src.id, grp_id]
                else:
                    rup_counter[src.id][rup.idx] += 1
                # Store info
                dt = time.time() - t0
                calc_times[src.id] += numpy.array([len(rup_data[src.id]),
                                                   src.nsites, dt])
        elif param['src_interdep'] == 'mutex':
            print('Not yet implemented')
            exit(0)
    # Create event based ruptures
    for src_key in rup_data:
        for rup_key in rup_data[src_key]:
            dat = rup_data[src_key][rup_key]
            cnt = rup_counter[src_key][rup_key]
            ebr = EBRupture(dat[0], dat[1], dat[2], cnt, samples)
            eb_ruptures.append(ebr)

    return eb_ruptures, calc_times, eff_ruptures, grp_id