#!/usr/bin/env python

# paultaney ta yahoo.com
# with kind assistance from Chris.Barker ta NOAA.gov
# and St\xe9fan on the scipy list (test7)

import wx
import numpy as np

YOU_HAVE_AN_IMAGE = 0
if YOU_HAVE_AN_IMAGE:
    path = "8bitchart01_small.tiff" # put its name here
    image = wx.Image(path, wx.BITMAP_TYPE_ANY)
    w, h = image.GetWidth(), image.GetHeight()
    # Rappin page 362, Smart page 285
    a = np.fromstring(image.GetData(), np.uint8)  
    a.reshape(w, h, 3)

else:
    # for testing:

    # gen test data (minus the commas)
    # data = np.random.randint(0,255,(5,5,3))
    # print "d = np.array(%s, np.uint8)" % (data) 

    a = np.array(       #  x  y
    [[[ 64, 237, 108],  # [0, 0]
      [185, 240,  68],  # [0, 1]      test five
      [ 17, 116,  55],  # [0, 2] is said to be blue (THIRD) XXX
      [107,  11, 185],  # [0, 3] is blue (SIXTH)
      [154,  30,  52]], # [0, 4]

     [[251,  73, 150],  # [1, 0]
      [ 47, 225,  97],  # [1, 1]
      [101,  91, 251],  # [1, 2] is blue (FOURTH)
      [ 61,  23,  79],  # [1, 3]
      [161,  22, 165]], # [1, 4]

     [[  4, 162, 188],  # [2, 0]
      [ 25, 131, 211],  # [2, 1] is blue (SECOND)
      [162, 112, 177],  # [2, 2]
      [169,  83, 214],  # [2, 3] is blue (not reported)
      [254, 139,  95]], # [2, 4]

     [[  2,  88, 216],  # [3, 0] is blue (FIRST)
      [230,  63, 192],  # [3, 1]
      [ 71,  78,  50],  # [3, 2] is said to be blue (FIFTH)
      [113, 151, 150],  # [3, 3] is said to be blue (SEVENTH)
      [104,  65, 250]], # [3, 4] is blue (EIGHTH)

     [[  6, 191, 220],  # [4, 0] is blue (not reported)
      [ 38, 141,   4],
      [245,  41,  23],
      [ 23, 127, 183],  # [4, 3] is blue (not reported)
      [165,  24,   5]]], np.uint8)

DIM = (5, 5)
def test1(a):

    red, grn, blu = a[0,0]
    print "r=%r, g=%r, b=%r" % (red, grn, blu)  # prints r=64, g=237, b=108

    red, grn, blu = a[4, 4]
    print "r=%r, g=%r, b=%r" % (red, grn, blu)  # prints r=165, g=24, b=5


def test2(a):
    # this is a threshold filter
    rmin, rmax, gmin, gmax, bmin, bmax = 0,178, 0,178, 178,255

    very_blue_pixels = []
    w = DIM[0] 
    x = y = 0
    # searches rows first (x is turning faster, so...)
    for xyslice in a:
        for xslice in xyslice:
            if 0: print "x=%r, y=%r, type(xslice)= %r" % (x, y, type(xslice))
            if 0: print "a[x=%i, y=%i] = %r" % (x, y, a[x,y])
            red, grn, blu = xslice
            if (rmin <= red <= rmax) and \
               (gmin <= grn <= gmax) and \
               (bmin <= blu <= bmax):
                if 1: print "a very blue pixel at x=%i, y=%i, rgb=%r" % (x, y, xslice)
                very_blue_pixels.append((x,y))
            x += 1
            if x==w: x=0  # ugly
        y += 1
    print "test2: very_blue_pixels=%r" % (very_blue_pixels)
#a very blue pixel at x=3, y=0, rgb=array([107,  11, 185], dtype=uint8)
#a very blue pixel at x=2, y=1, rgb=array([101,  91, 251], dtype=uint8)
#a very blue pixel at x=0, y=2, rgb=array([  4, 162, 188], dtype=uint8)
#a very blue pixel at x=1, y=2, rgb=array([ 25, 131, 211], dtype=uint8)
#a very blue pixel at x=3, y=2, rgb=array([169,  83, 214], dtype=uint8)
#a very blue pixel at x=0, y=3, rgb=array([  2,  88, 216], dtype=uint8)
#a very blue pixel at x=4, y=3, rgb=array([104,  65, 250], dtype=uint8)
#a very blue pixel at x=3, y=4, rgb=array([ 23, 127, 183], dtype=uint8)
#test2: very_blue_pixels=[(3, 0), (2, 1), (0, 2), (1, 2), (3, 2), (0, 3), (4, 3), (3, 4)]


def test3(a, THRESH):
    # for my dataset I can optimize the above loop like this 
    # at the cost of getting less output since the THRESHOLD is only one number
    # 
    very_blue_pixels = []
    w = DIM[0]
    x = y = 0
    for xyslice in a:
        for xslice in xyslice:
            red, grn, blu = xslice
            if (red <= THRESH) and (grn <= THRESH) and (THRESH <= blu):
                very_blue_pixels.append((x, y))
                if 1: print "I see blue a[x=%i, y=%i] pixel = %r" % (x, y, xslice)
            x += 1
            if x==w: x=0
        y += 1
    print "test3: very_blue_pixels=%r" % (very_blue_pixels)
#I see blue a[x=3, y=0] pixel = array([107,  11, 185], dtype=uint8)
#I see blue a[x=2, y=1] pixel = array([101,  91, 251], dtype=uint8)
#I see blue a[x=0, y=2] pixel = array([  4, 162, 188], dtype=uint8)
#I see blue a[x=1, y=2] pixel = array([ 25, 131, 211], dtype=uint8)
#I see blue a[x=3, y=2] pixel = array([169,  83, 214], dtype=uint8)
#I see blue a[x=0, y=3] pixel = array([  2,  88, 216], dtype=uint8)
#I see blue a[x=4, y=3] pixel = array([104,  65, 250], dtype=uint8)
#I see blue a[x=3, y=4] pixel = array([ 23, 127, 183], dtype=uint8)
#test3: very_blue_pixels=[(3, 0), (2, 1), (0, 2), (1, 2), (3, 2), (0, 3), (4, 3), (3, 4)]


def test4(a):
    RED, GRN, BLU = 0, 1, 2
    rmin, rmax, gmin, gmax, bmin, bmax = 0,178, 0,178, 100,255
    line_pix = ((rmin <= a[:, :, RED] <= rmax) &
                (gmin <= a[:, :, GRN] <= gmax) &
                (bmin <= a[:, :, BLU] <= bmax))
    print "test4: line_pix = %r" % (line_pix)
    # ValueError: The truth value of an array with more than 
    # one element is ambiguous. Use a.any() or a.all()

def test5(a, THRESH):
    RED, GRN, BLU = 0, 1, 2
    line_pix = ((a[:, :, RED] <= THRESH) &
                (a[:, :, GRN] <= THRESH) &
                (a[:, :, BLU] >= THRESH))
    print "test5: line_pix = %r" % (line_pix)
    return line_pix

#test5: line_pix = array(
#         x=0     1      2      3      4
# y=0   [[False, False, False,  True, False],  # [3, 0] is blue
#   1    [False, False,  True, False, False],  # [2, 1] is blue
#   2    [ True,  True, False,  True, False],  # [0, 2] xxx, [1, 2] is blue, [3, 2] xxx
#   3    [ True, False, False,  True, False],  # [0, 3] is blue, [4, 3]
#   4    [False, False, False,  True, False]]) # [3, 4] is blue

# cf test3:  [(3, 0), (2, 1), (0, 2), (1, 2), (3, 2), (0, 3), (4, 3), (3, 4)]

def test6(a, rmax, gmax, bmin):
    RED, GRN, BLU = 0, 1, 2
    line_pix = ((a[:, :, RED] <= rmax) &
                (a[:, :, GRN] <= gmax) &
                (a[:, :, BLU] >= bmin))
    print "test6: line_pix = %r" % (line_pix)

def dump_bool_array(b):
    very_blue_pixels = []
    w = DIM[0]
    x = y = 0
    for xyslice in b:
        for bool in xyslice:
            if bool:
                very_blue_pixels.append((x, y))
            x += 1
            if x==w: x=0
        y += 1
    print "dump_bool_array=%r" % (very_blue_pixels)
# [(3, 0), (2, 1), (0, 2), (1, 2), (3, 2), (0, 3), (4, 3), (3, 4)] # BINGO!

def test7(a, fact):
    RED, GRN, BLU = 0, 1, 2
    bluemask = (a[...,BLU] > fact*a[...,GRN]) & (a[...,2] > fact*a[...,RED])
    b = a[bluemask, :]
    print "test 7 with factor=%f" % fact
    return b

# test1(a)  # passed
# test2(a)  # passed
# test3(a, 178)  # passed
# test4(a)      # FAILS
# dump_bool_array(test5(a, 178))  # ???
# test6(a, 178, 178, 100)  # ???
print test7(a, 1.25)
print test7(a, 1.4)

#</code>
