# Path: lmatools/io/LMA_h5_file.py
# def read_flashes(h5LMAfiles, target, base_date=None, min_points=10):
#     """ This routine is the data pipeline source, responsible for pushing out
#         events and flashes. Using a different flash data source format is a matter of
#         replacing this routine to read in the necessary event and flash data."""
# 
#     # for filename in h5LMAfiles:
#         # h5 = LMAh5File(filename, min_points=min_points)
#         # for events, flashes in h5.gen_events_flashes():
#         #
#         #     # get the start date of the file, which is the seconds-of-day reference
#         #     h5_start =  h5.base_date
#         #     if base_date==None:
#         #         base_date = h5_start
#         #
#         #     # adjust time in seconds of day to be in correct reference
#         #     extra_dt = to_seconds(h5_start - base_date)
#         #     events['time'] += extra_dt
#         #     flashes['start'] += extra_dt
#         #
#         #     n_flashes = len(flashes)
#         #     print('{0} -- {1} flashes > {2} pts; dt+={3}  '.format(filename, n_flashes, min_points, extra_dt))
# 
#     h5s = LMAh5Collection(h5LMAfiles, base_date=base_date, min_points=min_points)
#     for push_out in h5s: # get a stream of events, flashes
#         target.send(push_out)
#         del push_out
# 
# Path: lmatools/stream/subset.py
# def coroutine(func):
#     def start(*args,**kwargs):
#         cr = func(*args,**kwargs)
#         next(cr)
#         return cr
#     return start
# 
# class Branchpoint(object):
#     """ Class-based version useful for tracking a changing state or adjusting targets
#         at a later time. Some '.dot' access overhead this way, of course.
# 
#         >>> brancher = Branchpoint( [target1, target2, ...] )
# 
#         Allows for flexible branching by maintaining a set (in the formal sense) of targets.
#         brancher.targets.append(newtarget)
#         brancher.targets.remove(existingtarget)
#     """
# 
#     def __init__(self, targets): 
#         """ Accepts a sequence of targets """
#         self.targets = set(targets) # this perhaps should be a set and not a list, so it remains unique
# 
#     @coroutine
#     def broadcast(self):
#         while True:
#             stuff = (yield)
#             for target in self.targets:
#                 target.send(stuff)
#             del stuff
# 
# Path: lmatools/flashsort/flash_stats.py
# def hull_volume(xyz):
#     """ Calculate the volume of the convex hull of 3D (X,Y,Z) LMA data.
#         xyz is a (N_points, 3) array of point locations in space. """
#     assert xyz.shape[1] == 3
#         
#     tri = Delaunay(xyz[:,0:3])
#     vertices = tri.points[tri.vertices]
#     
#     # This is the volume formula in 
#     # https://github.com/scipy/scipy/blob/master/scipy/spatial/tests/test_qhull.py#L106
#     # Except the formula needs to be divided by ndim! to get the volume, cf., 
#     # http://en.wikipedia.org/wiki/Simplex#Geometric_properties
#     # Credit Pauli Virtanen, Oct 14, 2012, scipy-user list
#     
#     q = vertices[:,:-1,:] - vertices[:,-1,None,:]
#     simplex_volumes = (1.0 / factorial(q.shape[-1])) * np.fromiter(
#            (np.linalg.det(q[k,:,:]) for k in range(tri.nsimplex)) , dtype=float)
#     # print vertices.shape # number of simplices, points per simplex, coords
#     # print q.shape
#     
#     # The simplex volumes have negative values since they are oriented 
#     # (think surface normal direction for a triangle
#     volume=np.sum(np.abs(simplex_volumes))
#     return volume, vertices, simplex_volumes


import glob
import os
import numpy as np
        import matplotlib.pyplot as plt
    import matplotlib.pyplot as plt
    import matplotlib.pyplot as plt
        import matplotlib.pyplot as plt
from lmatools.io.LMA_h5_file import read_flashes
from lmatools.stream.subset import coroutine, Branchpoint
from lmatools.flashsort.flash_stats import hull_volume
from __future__ import absolute_import
from __future__ import print_function




def gen_flash_events(events, flashes):
    """ Given events and flashes tables, generate
        events for each flash as (events, flash)
    """
    for fl in flashes:
        fl_id=fl['flash_id']
        this_flash = (events['flash_id']==fl_id)
        yield events[this_flash], fl

def length_from_area(A,D,b_s):
    return ( (np.sqrt(A))**D ) / (b_s**(D-1))

def volumetric_length_from_points(x,y,z,D, b_s):
    xyz = np.vstack((x,y,z)).T
    

# Path: lmatools/io/LMA_h5_file.py
# def read_flashes(h5LMAfiles, target, base_date=None, min_points=10):
#     """ This routine is the data pipeline source, responsible for pushing out
#         events and flashes. Using a different flash data source format is a matter of
#         replacing this routine to read in the necessary event and flash data."""
# 
#     # for filename in h5LMAfiles:
#         # h5 = LMAh5File(filename, min_points=min_points)
#         # for events, flashes in h5.gen_events_flashes():
#         #
#         #     # get the start date of the file, which is the seconds-of-day reference
#         #     h5_start =  h5.base_date
#         #     if base_date==None:
#         #         base_date = h5_start
#         #
#         #     # adjust time in seconds of day to be in correct reference
#         #     extra_dt = to_seconds(h5_start - base_date)
#         #     events['time'] += extra_dt
#         #     flashes['start'] += extra_dt
#         #
#         #     n_flashes = len(flashes)
#         #     print('{0} -- {1} flashes > {2} pts; dt+={3}  '.format(filename, n_flashes, min_points, extra_dt))
# 
#     h5s = LMAh5Collection(h5LMAfiles, base_date=base_date, min_points=min_points)
#     for push_out in h5s: # get a stream of events, flashes
#         target.send(push_out)
#         del push_out
# 
# Path: lmatools/stream/subset.py
# def coroutine(func):
#     def start(*args,**kwargs):
#         cr = func(*args,**kwargs)
#         next(cr)
#         return cr
#     return start
# 
# class Branchpoint(object):
#     """ Class-based version useful for tracking a changing state or adjusting targets
#         at a later time. Some '.dot' access overhead this way, of course.
# 
#         >>> brancher = Branchpoint( [target1, target2, ...] )
# 
#         Allows for flexible branching by maintaining a set (in the formal sense) of targets.
#         brancher.targets.append(newtarget)
#         brancher.targets.remove(existingtarget)
#     """
# 
#     def __init__(self, targets): 
#         """ Accepts a sequence of targets """
#         self.targets = set(targets) # this perhaps should be a set and not a list, so it remains unique
# 
#     @coroutine
#     def broadcast(self):
#         while True:
#             stuff = (yield)
#             for target in self.targets:
#                 target.send(stuff)
#             del stuff
# 
# Path: lmatools/flashsort/flash_stats.py
# def hull_volume(xyz):
#     """ Calculate the volume of the convex hull of 3D (X,Y,Z) LMA data.
#         xyz is a (N_points, 3) array of point locations in space. """
#     assert xyz.shape[1] == 3
#         
#     tri = Delaunay(xyz[:,0:3])
#     vertices = tri.points[tri.vertices]
#     
#     # This is the volume formula in 
#     # https://github.com/scipy/scipy/blob/master/scipy/spatial/tests/test_qhull.py#L106
#     # Except the formula needs to be divided by ndim! to get the volume, cf., 
#     # http://en.wikipedia.org/wiki/Simplex#Geometric_properties
#     # Credit Pauli Virtanen, Oct 14, 2012, scipy-user list
#     
#     q = vertices[:,:-1,:] - vertices[:,-1,None,:]
#     simplex_volumes = (1.0 / factorial(q.shape[-1])) * np.fromiter(
#            (np.linalg.det(q[k,:,:]) for k in range(tri.nsimplex)) , dtype=float)
#     # print vertices.shape # number of simplices, points per simplex, coords
#     # print q.shape
#     
#     # The simplex volumes have negative values since they are oriented 
#     # (think surface normal direction for a triangle
#     volume=np.sum(np.abs(simplex_volumes))
#     return volume, vertices, simplex_volumes


# Path: lmatools/flash_stats.py
import glob
import os
import numpy as np
        import matplotlib.pyplot as plt
    import matplotlib.pyplot as plt
    import matplotlib.pyplot as plt
        import matplotlib.pyplot as plt
from lmatools.io.LMA_h5_file import read_flashes
from lmatools.stream.subset import coroutine, Branchpoint
from lmatools.flashsort.flash_stats import hull_volume

from __future__ import absolute_import
from __future__ import print_function




def gen_flash_events(events, flashes):
    """ Given events and flashes tables, generate
        events for each flash as (events, flash)
    """
    for fl in flashes:
        fl_id=fl['flash_id']
        this_flash = (events['flash_id']==fl_id)
        yield events[this_flash], fl

def length_from_area(A,D,b_s):
    return ( (np.sqrt(A))**D ) / (b_s**(D-1))

def volumetric_length_from_points(x,y,z,D, b_s):
    xyz = np.vstack((x,y,z)).T
    

    volume, vertices, simplex_volumes = hull_volume(xyz)