#! /usr/bin/python
# encoding: utf-8

step_dps_revision = "$Revision: 5185 $"

import sys
if "solopath" not in sys.modules: 
    sys.path[1:1] = [".."]

import dps_table

import math
import numpy

emin = 0.016
nume = 256
emax = emin*2**(nume/16)

ebins = numpy.logspace(numpy.log2(emin),numpy.log2(emax), nume, base=2, endpoint=False)

chbins = numpy.arange(16)

def xyhist(self,a,xmin,xmax,xbins,hx=1,dx=0,ymin=None,ymax=None,ybins=None,hy=1,dy=0,section=None,*args,**kwargs):
    import bisect

    imin = bisect.bisect_left(xbins,xmin)
    imax = bisect.bisect_left(xbins,xmax)
    nix = (imax-imin)

    a += imin
    nx = int(numpy.ceil(nix / hx))

    ny = 1
    sy = 0
    if ymin is not None and ymax is not None and ybins is not None:
        imin = bisect.bisect_left(ybins,ymin)
        imax = bisect.bisect_left(ybins,ymax)
        niy = (imax-imin)

        a += imin * len(xbins)
        ny = int(numpy.ceil(niy / hy))
        sy = len(xbins)
    
    dy = dy + sy - (nx - 1)
    
    self.histogram(dps_item(a=a, nx=nx, ny=ny, sy=sy, section=section, *args, **kwargs),hx=hx,hy=hy,dx=dx,dy=dy)

def write_sci_defs(f, d):
    f = open(f, 'w')
    for dd in d:
        f.write(repr(dd)+"\n")
    f.close()

class sci_prod(object):
    def __init__(self, prod, idx, a, xmin, xmax, hx, dx, ymin, ymax, hy, dy, section, csum, cenc=0, *args, **kwargs):
        self.prod = prod
        self.idx = idx
        self.a = a
        self.xmin = xmin
        self.xmax = xmax
        self.hx = hx
        self.dx = dx
        self.ymin = ymin
        self.ymax = ymax
        self.hy = hy
        self.dy = dy
        self.section = section
        self.csum = csum
        self.cenc = cenc

    def __repr__(self):
        s = ""
        s += "0x%04x/%d[%d]"%(0x0300 | self.prod.args['tag'], self.prod.args['flg'], self.idx)
        s += " %d %.3f %.3f %d %d %d %d %d %d"%(self.a, self.xmin, self.xmax, self.hx, self.dx, self.ymin, self.ymax, self.hy, self.dy)
        s += " %d %d"%(self.csum, self.cenc)
        s += " %s"%self.section
        return s

def stephist(self,a,xmin,xmax,hx=1,dx=0,ymin=None,ymax=None,hy=1,dy=0,section=None,*args,**kwargs):
    xyhist(self,a,xmin,xmax,xbins=ebins,hx=hx,dx=dx,ymin=ymin,ymax=ymax,ybins=chbins,hy=hy,dy=dy,section=section,*args,**kwargs)


dps_table.dps_product.xyhist = xyhist
dps_table.dps_product.stephist = stephist

from dps_table import *

class step_dps(dps_table):

    revision = "$Revision: 5185 $"

    HIST_BASE = 0x4000
    IX0 = HIST_BASE+0x0000
    IX1 = HIST_BASE+0x1000
    IX0_MULT = HIST_BASE+0x2000
    IX1_MULT = HIST_BASE+0x2100

    IX0_MULT += 1 # ignore zero multiplicity hits
    IX1_MULT += 1 # dto

    PIXEL = nume             # number of energy channels per pixel
    SMALL_PIXELS = PIXEL*16 # offset of small pixel histograms

    def __init__(self):
        dps_table.__init__(self)
        if dps_table.revision > self.revision:
            self.revision = dps_table.revision
        self.assemble()

    def assemble(self):
        self.do_clear()
        self.do_nominal()
        self.do_burst()
        self.do_lowlatency()
        self.allocate()
        self.normalize()

    def do_clear(self):
        self += dps_product("clear", drop=True)
        self["clear"].add(dps_item(self.HIST_BASE, nx=256, ny=256, sy=256, clear=True, tele=False))

    def do_nominal(self):
        self += dps_product("nominal",   tag=0x53, flg=0, tmod="5s")
        t = self["nominal"]

        ix0 = self.IX0
        ix1 = self.IX1
        ix0_mult = self.IX0_MULT
        ix1_mult = self.IX1_MULT
        pixel = self.PIXEL

        t.stephist(ix0, xmin=2, xmax=96, hx=14, ymin=0, ymax=16, hy=16, csum="60s", cenc="300s", clear=False, tele=True, add=False, section="electrons_basic") # electron basic data product

        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=1, ymax=3, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=3, ymax=4, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=4, ymax=6, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=6, ymax=8, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=8, ymax=9, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=9, ymax=11, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=11, ymax=13, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=13, ymax=14, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=8, ymin=14, ymax=16, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot

        t.stephist(ix0, xmin=2, xmax=96, hx=4, ymin=1, ymax=16, hy=3, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_t_res") # electron high time-resolution projections, rows
        t.stephist(ix0, xmin=2, xmax=96, hx=4, ymin=1, ymax=16, hy=5, dy=5*pixel, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electrons_t_res") # electron high time-resolution projections, columns

        t.stephist(ix1, xmin=2, xmax=96, hx=14, ymin=0, ymax=16, hy=16, csum="60s", cenc="300s", clear=False, tele=True, add=False, section="protons_basic") # proton basic data product

        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=1, ymax=3, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=3, ymax=4, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=4, ymax=6, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=6, ymax=8, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=8, ymax=9, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=9, ymax=11, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=11, ymax=13, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=13, ymax=14, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=8, ymin=14, ymax=16, hy=1, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot

        t.stephist(ix1, xmin=2, xmax=96, hx=4, ymin=1, ymax=16, hy=3, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_t_res") # proton high time-resolution projections, rows
        t.stephist(ix1, xmin=2, xmax=96, hx=4, ymin=1, ymax=16, hy=5, dy=5*pixel, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="protons_t_res") # proton high time-resolution projections, columns

        t.histogram(dps_item(a=ix0_mult, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="electron_multiplicities"), hx=15) # electron multiplicities
        t.histogram(dps_item(a=ix1_mult, csum="5s", cenc="60s", clear=False, tele=True, add=False, section="proton_multiplicities"), hx=15) # proton multiplicities


    def do_burst(self):
        self += dps_product("burst",    tag=0x63, flg=0, tmod="5s")
        t = self["burst"]

        ix0 = self.IX0
        ix1 = self.IX1
        ix0_mult = self.IX0_MULT
        ix1_mult = self.IX1_MULT
        pixel = self.PIXEL

        t.stephist(ix0, xmin=2, xmax=96, hx=14, ymin=0, ymax=16, hy=16, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="electrons_t_res") # electron high-resolution spectra
        t.stephist(ix0, xmin=2, xmax=96, hx=14, ymin=1, ymax=16, hy=3, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot

        t.stephist(ix1, xmin=2, xmax=96, hx=14, ymin=0, ymax=16, hy=16, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="protons_t_res") # proton high-resolution spectra
        t.stephist(ix1, xmin=2, xmax=96, hx=14, ymin=1, ymax=16, hy=3, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot

        t.histogram(dps_item(a=ix0_mult, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="electron_multiplicities"), hx=15) # electron multiplicities
        t.histogram(dps_item(a=ix1_mult, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="proton_multiplicities"), hx=15) # proton multiplicities


    def do_lowlatency(self):
        self += dps_product("lowlatency",tag=0x33, flg=0, tmod="5s")
        t = self["lowlatency"]

        ix0 = self.IX0
        ix1 = self.IX1
        ix0_mult = self.IX0_MULT
        ix1_mult = self.IX1_MULT
        pixel = self.PIXEL
        
        t.stephist(ix0, xmin=2, xmax=96, hx=14, ymin=0, ymax=16, hy=16, csum="600s", cenc="3600s", clear=False, tele=True, add=False, section="electrons_basic") # electron basic data product
        t.stephist(ix0, xmin=2, xmax=96, hx=4, ymin=0, ymax=16, hy=16, csum="60s", cenc="600s", clear=False, tele=True, add=False, section="electrons_pitchangles") # electron pitch-angle snapshot
        t.stephist(ix0, xmin=2, xmax=96, hx=1, ymin=0, ymax=16, hy=1, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="electrons_sum") # electron sum of all pixels

        t.stephist(ix1, xmin=2, xmax=96, hx=14, ymin=0, ymax=16, hy=16, csum="600s", cenc="3600s", clear=False, tele=True, add=False, section="protons_basic") # proton basic data product
        t.stephist(ix1, xmin=2, xmax=96, hx=4, ymin=0, ymax=16, hy=16, csum="60s", cenc="600s", clear=False, tele=True, add=False, section="protons_pitchangles") # proton pitch-angle snapshot
        t.stephist(ix1, xmin=2, xmax=96, hx=1, ymin=0, ymax=16, hy=1, csum="5s", cenc="300s", clear=False, tele=True, add=False, section="protons_sum") # proton sum of all pixels

        t.histogram(dps_item(a=ix0_mult, csum="600s", cenc="3600s", clear=False, tele=True, add=False, section="electron_multiplicities"), hx=15) # electron multiplicities
        t.histogram(dps_item(a=ix1_mult, csum="600s", cenc="3600s", clear=False, tele=True, add=False, section="proton_multiplicities"), hx=15) # proton multiplicities

    def write_defs_file(self, fn="step_dps.defs"):
        with open(fn, 'w') as defs:
             
            self.write_defs(defs)
            
            # Write small pixel defs
            for prod in self.products.itervalues():
                if "flg" in prod.args:
                    prod.args["flg"] = 1
            self.write_defs(defs)
            
            for prod in self.products.itervalues():
                if "flg" in prod.args:
                    prod.args["flg"] = 0


from solomsgclass import msg_print
if __name__ == '__main__':
    import sys
    import os
    d = step_dps()
    fn = os.path.splitext(sys.argv[0])
    d.write_defs_file(fn[0]+".defs")

