#!/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
