#!/usr/bin/env python
# WedgeExpert.py
#
#   Copyright (C) 2009 Diamond Light Source, Graeme Winter
#
#   This code is distributed under the BSD license, a copy of which is
#   included in the root directory of this package.
#
# Some code to help figure out how the experiment was performed and tell
# Chef where we could consider cutting the data at... N.B. this will now
# take the digested wedges from the Chef wrapper.

import math
import sys
import pickle

def digest_wedges(wedges):
    '''Digest the wedges defined as a list of

    FIRST_DOSE FIRST_BATCH SIZE EXPOSURE DATASET

    to a set of potential "stop" points, in terms of the doses. This will
    return a list of DOSE values which should be treated as LIMITS (i.e.
    d:d < DOSE ok).'''

    # first digest to logical sweeps, keyed by the last image in the set
    # and the wavelength name, and containing the start and end dose.

    if False:
        return

    doses = { }

    belonging_wedges = { }

    for w in wedges:
        dose, batch, size, exposure, dataset = w
        if (dataset, batch) in doses:
            k_old = (dataset, batch)
            k_new = (dataset, batch + size)

            sweep = doses[k_old]
            doses[k_new] = (sweep[0], sweep[1] + exposure * size)

            belonging_wedges[k_new] = belonging_wedges[k_old]
            belonging_wedges[k_new].append(w)

            del(doses[k_old])
            del(belonging_wedges[k_old])

        else:
            end_dose = dose + exposure * (size - 1)

            doses[(dataset, batch + size)] = (dose, end_dose)
            belonging_wedges[(dataset, batch + size)] = [w]

    # now invert

    sweeps = { }

    for k in doses:
        sweeps[doses[k]] = k

    # now try to figure the sweeps which are overlapping - these will be
    # added to a list named "groups"

    groups = []

    last_time = sorted(sweeps)[0][0] - 1.0

    for s in sorted(sweeps):
        if s[0] > last_time:
            last_time = s[1]
            groups.append([s])
        else:
            last_time = s[1]
            groups[-1].append(s)

    dmaxes = []

    group_report = []

    for j, g in enumerate(groups):

        # check that the group structure is correct, i.e. all have the
        # uniform number of wedges...

        group_wedges = { }

        for s in g:
            all_wedges = belonging_wedges[sweeps[s]]
            dataset = all_wedges[0][-1]
            last_image = int(s[1])

            # Boom! this is wrong for inverse beam data sets

            group_wedges[(dataset, last_image)] = all_wedges

        size = 0

        datasets = list(set([k[0] for k in group_wedges]))

        if len(g) == 1:
            assert(len(belonging_wedges[sweeps[g[0]]]) == 1)
            group_report.append('Single wedge')
        elif len(datasets) == 1:
            assert(len(group_wedges) == 2)
            group_report.append('Inverse beam')
        else:
            group_report.append('%d-wedge data collection' % \
                                len(group_wedges))

        for dataset, last_image in group_wedges:
            if not size:
                size = len(group_wedges[(dataset, last_image)])

            assert(size == len(group_wedges[(dataset, last_image)]))

        for j in range(size):

            d_local = []

            for s in g:
                bw = belonging_wedges[sweeps[s]][j]
                d_local.append(bw[0] + bw[2] * bw[3])

            dmaxes.append(max(d_local))

    return dmaxes, group_report

if __name__ == '__main__':

    wedges = pickle.loads(open('test.pkl').read())

    dmaxes, group_report = digest_wedges(wedges)

    for gr in group_report:
        print gr
