Exemplo n.º 1
0
    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.hsv_color = colorsys.rgb_to_hsv(0.0, 0.0, 1.0)
        self.hex_color = '#0000ff'
        self.color_list = ["red","blue","green","orange","purple"]
        self.parent = parent
        print "Loading model..."
        self.lux = Lux()
        fp = open(curdir+"/gauss_model.pkl"); self.gm = pickle.load(fp); fp.close()
        fp = open(curdir+"/memoized_binomial_data.pkl"); self.curve_data = pickle.load(fp); fp.close()
        fp = open(curdir+"/sampling_normalizer.pkl"); self.normalizer = pickle.load(fp); fp.close()
        print "Creating UI"
        self.initUI()
        self.update_output()
        self.replot()
Exemplo n.º 2
0
    def __init__(self, parent):
        Frame.__init__(self, parent)   
         
        self.hsv_color = colorsys.rgb_to_hsv(0.0, 0.0, 1.0)
        self.hex_color = '#0000ff'
        # Added second copy of the above two fields for second color
        # For debugging, want an initial 
        if self.debug :
            self.hsv_colorTwo = colorsys.rgb_to_hsv(0.0, 0.50, 0.625)
            self.hex_colorTwo = '#0088aa'
        else:
            self.hsv_colorTwo = colorsys.rgb_to_hsv(1.0, 0.0, 0.0)
            self.hex_colorTwo = '#ff0000'
        
        self.parent = parent  
	print "Loading model..."      
        self.lux = Lux()
        self.initUI()
Exemplo n.º 3
0
class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.hsv_color = colorsys.rgb_to_hsv(0.0, 0.0, 1.0)
        self.hex_color = '#0000ff'
        self.color_list = ["red","blue","green","orange","purple"]
        self.parent = parent
        print "Loading model..."
        self.lux = Lux()
        fp = open(curdir+"/gauss_model.pkl"); self.gm = pickle.load(fp); fp.close()
        fp = open(curdir+"/memoized_binomial_data.pkl"); self.curve_data = pickle.load(fp); fp.close()
        fp = open(curdir+"/sampling_normalizer.pkl"); self.normalizer = pickle.load(fp); fp.close()
        print "Creating UI"
        self.initUI()
        self.update_output()
        self.replot()

    def update_output(self):
        (h, s, v) = self.hsv_color
        self.hsv_var.set("Hue: \t %2.1f \nSat:\t %2.1f \nValue:\t %2.1f" % (h*360,s*100,v*100))
        items = self.lux.full_posterior((h * 360, s * 100, v * 100))
        self.current_post = items
        desc = [ '{:<25} ({:.3f})\n'.format(items[i][0], items[i][1]) for i in range(25) ]
        self.display.config(state=NORMAL)
        self.display.delete(0, END)

        for i in range(25): self.display.insert(END, '{:<20} ({:.3f})'.format(items[i][0], items[i][1]))

        self.display.select_set(0, 0)

    def plot_lux_model(self, params,ax1,label,support,dim):
        cur_color='black'
        mu1,sh1,sc1,mu2,sh2,sc2 = params
        left_stach=gam_dist(sh1,scale=sc1); lbounds=left_stach.interval(0.99)
        right_stach=gam_dist(sh2,scale=sc2); rbounds=right_stach.interval(0.99)
        lx=np.linspace(mu1,-180); rx=np.linspace(mu2,360)
        s=3;
        ax1.plot(rx, [right_stach.sf(abs(y-mu2)) for y in rx],linewidth=s,c=cur_color);
        ax1.plot([1.01*mu1,0.99*mu2], [1.,1.], linewidth=s,c=cur_color)
        return ax1.plot(lx,[left_stach.sf(abs(y-mu1)) for y in lx],c=cur_color, linewidth=s);

    def plot_gm_model(self, params, ax, label, support):
        s=3
        x = np.linspace(support[0],support[1],360)

        return ax.plot(x,norm.pdf(x,params[0],params[1]),c='red', linewidth=s), norm.pdf([params[0]],params[0],[params[1]])[0]


    def initUI(self):

        self.parent.title("Interactive LUX visualization")
        self.pack(fill=BOTH, expand=1)

        self.color_frame = Frame(self, border=1)
        self.color_frame.pack(side=LEFT)

        probe_title_var = StringVar(); probe_title_label = Label(self.color_frame, textvariable=probe_title_var, justify=CENTER,  font = "Helvetica 16 bold italic")
        probe_title_var.set("Color Probe X"); probe_title_label.pack(side=TOP)

        self.hsv_var = StringVar()
        self.hsv_label = Label(self.color_frame, textvariable=self.hsv_var,justify=LEFT)
        h,s,v = self.hsv_color
        self.hsv_var.set("Hue: %2.1f \nSaturation: %2.1f \nValue: %2.1f" % (h*360,s*100,v*100))
        self.hsv_label.pack(side=TOP)

        self.frame = Frame(self.color_frame, border=1,
            relief=SUNKEN, width=200, height=200)

        self.frame.pack(side=TOP)
        self.frame.config(bg=self.hex_color)
        self.frame.bind("<Button-1>",self.onChoose)


        self.btn = Button(self.color_frame, text="Select Color",
            command=self.onChoose)
        self.btn.pack(side=TOP)

        posterior_title_var = StringVar(); posterior_title_label = Label(self.color_frame, textvariable=posterior_title_var, justify=CENTER, font = "Helvetica 16 bold italic")
        posterior_title_var.set("\n\nLUX's Posterior"); posterior_title_label.pack(side=TOP)

        Label(self.color_frame, text="Double click to show details \n(Wait time dependent on computer)").pack(side=TOP)



        my_font = tkFont.Font(family="Courier", size=10)
        self.display = Listbox(self.color_frame, border=1,
            relief=SUNKEN, width=30, height=25, font=my_font)
        self.display.pack(side=TOP,fill=Y,expand=1)
        self.display.bind("<Double-Button-1>",self.onSelect)
        self.display_btn = Button(self.color_frame, text="Show details", command=self.onSelect)
        self.display_btn.pack(side=TOP)

        self.update_output()



        self.fig = Figure(figsize=(10,4), dpi=100)

        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=1)
        self.canvas._tkcanvas.pack(side='top', fill='both', expand=1)

    def replot(self):

        def gb(x,i,t):
            #t is max value, i in number of bins, x is the thing to be binned
            if x==t:
                return i-1
            elif x==0.0:
                return 0
            return int(floor(float(x)*i/t))
        hsv_title = []
        j=self.display.curselection()[0]
        name = self.current_post[j][0]
        mult = lambda x: reduce(operator.mul, x)
        g_labels = []; lux_labels=[]; all_g_params=[]
        for i in range(3):

            def align_yaxis(ax1, v1, ax2, v2):
                """adjust ax2 ylimit so that v2 in ax2 is aligned to v1 in ax1"""
                _, y1 = ax1.transData.transform((0, v1))
                _, y2 = ax2.transData.transform((0, v2))
                inv = ax2.transData.inverted()
                _, dy = inv.transform((0, 0)) - inv.transform((0, y1-y2))
                miny, maxy = ax2.get_ylim()

                ax2.set_ylim(miny, maxy+dy)

            subplot = self.fig.add_subplot(4,1,i+1)
            dim_label = ["H", "S","V"][i]
            subplot.set_ylabel(r"$P(k^{true}_{%s}|x)$" % ["H", "S","V"][i] )

            curve_data = self.curve_data[name][i]

            scale = lambda x,a=0.3,b=0.9: (b-a)*(x)+a
            p_x = lambda x: self.normalizer[i][gb(x,len(self.normalizer[i]),[360,100,100][i])]
            max_p_x = max(self.normalizer[i])
            #1 is white, 0 is black. so we want highly probable thigns to be black..


            if self.lux.get_adj(self.current_post[j][0]):
                support = [[-180,180], [0,100],[0,100]][i]
                pp = lambda x,i: x-360 if i==0 and x>180 else x
                hacky_solution = [360,100,100][i]
                w = 1.5 if i==0 else 1

                conv = lambda x: x*support[1]/len(curve_data)
                bar_colors = ["%s" % (scale(1-p_x(conv(x))/max_p_x)) for x in range(len(curve_data))]
                bar1 = subplot.bar([pp(atan2(sin((x*hacky_solution/len(curve_data))*pi/180),cos((x*hacky_solution/len(curve_data))*pi/180))*180/pi,i) for x in range(len(curve_data))],[x/max(curve_data) for x in curve_data], label="%s data" % j,ec="black",width=w,linewidth=0,color=bar_colors)
            else:
                support = [[0,360], [0,100],[0,100]][i]
                w = 1.5 if i==0 else 1
                conv = lambda x: x*support[1]/len(curve_data)
                bar_colors = ["%s" % (scale(1-p_x(conv(x))/max_p_x)) for x in range(len(curve_data))]
                bar1 = subplot.bar([x*support[1]/len(curve_data) for x in range(len(curve_data))],[x/max(curve_data) for x in curve_data], label="%s data" % name[0],ec="black",width=w,linewidth=0,color=bar_colors)
                pp = lambda x,*args: x

            point = pp(self.hsv_color[i]*[360,100,100][i],i)
            hsv_title.append(point)
            probeplot = subplot.plot([point,point], [0,1],linewidth=3,c='blue',label="Probe")

            #for j in range(5):
            lux_plot = self.plot_lux_model(self.lux.get_params(self.current_post[j][0])[i], subplot, self.current_post[j][0],support, i)
            subplot2 = subplot.twinx()
            gm_plot,gm_height = self.plot_gm_model([pp(g_param,i) for g_param in self.gm[self.current_post[j][0]][0][i]], subplot2, self.current_post[j][0], support)
            extra = Rectangle((0, 0), 1, 1, fc="w", fill=False, edgecolor='none', linewidth=0)

            subplot.legend([extra], [["Hue", "Saturation", "Value"][i]],loc=2,frameon=False)


            if i==0: legend_set=lux_plot+[extra,extra,extra]+gm_plot+[extra,extra,extra]
            lux_params = self.lux.get_params(self.current_post[j][0])[i]
            g_params = [pp(g_param,i) for g_param in self.gm[self.current_post[j][0]][0][i]]
            all_g_params.append(g_params)

            g_labels.append(r"$\mu^{%s}=$%2.2f, $\sigma^{%s}$=%2.2f" % (dim_label, g_params[0],dim_label,g_params[1]))
            #lux_labels.append(r"$\mu^{L,%s}=$%2.2f, $E[\tau^{L,%s}]$=%2.2f, $\alpha^{L,%s}$=%2.2f, $\beta^{L,%s}$=%2.2f, $\mu^{U,%s}=$%2.2f, $E[\tau^{L,%s}]$=%2.2f, $\alpha^{U,%s}$=%2.2f, $\beta^{U,%s}$=%2.2f" % (dim_label, lux_params[0],dim_label, (lux_params[0]-lux_params[1]*lux_params[2]),dim_label,lux_params[1],dim_label, lux_params[2],dim_label,lux_params[3],dim_label,(lux_params[3]+lux_params[4]*lux_params[5]),dim_label, lux_params[4],dim_label,lux_params[5]))
            lux_labels.append(r"$\mu^{L,%s}=$%2.2f, $\alpha^{L,%s}$=%2.2f, $\beta^{L,%s}$=%2.2f, $\mu^{U,%s}=$%2.2f,  $\alpha^{U,%s}$=%2.2f, $\beta^{U,%s}$=%2.2f" % (dim_label, lux_params[0],dim_label, lux_params[1],dim_label, lux_params[2],dim_label,lux_params[3],dim_label,lux_params[4],dim_label,lux_params[5]))

            subplot.set_xlim(support[0],support[1])
            subplot.set_ylim(0,1.05)
            subplot2.set_xlim(support[0],support[1])
            subplot2.set_ylabel(r"$P(x|Gaussian_{%s})$" % ["H", "S","V"][i])
            align_yaxis(subplot, 1., subplot2, gm_height)


        leg_loc =(0.9,0.2)

        datum = [x*[360,100,100][i] for i,x in enumerate(self.hsv_color)];  phi_value = self.lux.get_phi(datum,self.current_post[j][0])
        #gauss_value = mult([norm.pdf(datum[i],all_g_params[i][0],all_g_params[i][1]) for i in range(3)])
        leg=self.fig.legend(probeplot+legend_set, ["Probe X"]+ [r"$\mathbf{\phi}_{%s}(X)=\mathbf{%2.5f}$; $\mathbf{\alpha}=\mathbf{%2.4f}$" % (self.current_post[j][0],phi_value,self.lux.get_avail(self.current_post[j][0]))]+lux_labels+
                                     [r"$Normal^{Hue}_{%s}$; $prior(%s)=%2.4f$" % (self.current_post[j][0],self.current_post[j][0], self.gm[self.current_post[j][0]][2])]+[g_labels[0]+"; "+g_labels[1]+"; "+g_labels[2]]
                                     , loc=8, handletextpad=4,labelspacing=0.1)


        self.fig.suptitle("%s" % name, size=30)

        print "done replotting"

    def onChoose(self, *args):
        try:
            ((red,green,blue), hx) = tkColorChooser.askcolor()
        except:
            print "I think you hit cancel"
            return
        self.hex_color = hx
        self.hsv_color = colorsys.rgb_to_hsv(red/255.0, green/255.0, blue/255.0)
        self.frame.config(bg=hx)
        self.update_output()
        self.fig.clear()
        self.replot()
        self.canvas.draw()

    def onSelect(self, *args):
        self.fig.clear()
        self.replot()
        self.canvas.draw()
Exemplo n.º 4
0
class Example(Frame):

    output_lines = 10
    # make debug false when you are actually going to demo this to an audience
    debug = 1
        
    def __init__(self, parent):
        Frame.__init__(self, parent)   
         
        self.hsv_color = colorsys.rgb_to_hsv(0.0, 0.0, 1.0)
        self.hex_color = '#0000ff'
        # Added second copy of the above two fields for second color
        # For debugging, want an initial 
        if self.debug :
            self.hsv_colorTwo = colorsys.rgb_to_hsv(0.0, 0.50, 0.625)
            self.hex_colorTwo = '#0088aa'
        else:
            self.hsv_colorTwo = colorsys.rgb_to_hsv(1.0, 0.0, 0.0)
            self.hex_colorTwo = '#ff0000'
        
        self.parent = parent  
	print "Loading model..."      
        self.lux = Lux()
        self.initUI()

    def update_output(self):
        (h, s, v) = self.hsv_color
        self.cv.set('Color {:.2f} {:.2f} {:.2f} (hsv)'.format(h, s, v))
        
    #tjm Added second update_output method for when second color is chosen 
    def update_outputTwo(self):
        (h, s, v) = self.hsv_colorTwo
        self.cvTwo.set('Color {:.2f} {:.2f} {:.2f} (hsv)'.format(h, s, v))
       
    def initUI(self):

        row_height = 220
        start_height = 30
        left_column = 30
        sq_size = 180
        color_column = left_column
        assoc_column = color_column + sq_size + 30
        dist_column = assoc_column + 220
        
        y_label = 5
        self.parent.title("Interactive LUX visualization")      
        self.pack(fill=BOTH, expand=1)
        
        self.frame = Frame(self, border=1, relief=SUNKEN, width=sq_size, height=sq_size)
        self.frame.place(x=color_column, y=start_height)
        self.frame.config(bg=self.hex_color)
        self.frame.bind("<Button-1>", self.onChooseClick)

        #tjm Added second color display window
        self.frameTwo = Frame(self, border=1, relief=SUNKEN, width=sq_size, height=sq_size)
        self.frameTwo.place(x=color_column, y=start_height+row_height)
        self.frameTwo.config(bg=self.hex_colorTwo)
        self.frameTwo.bind("<Button-1>", self.onChooseTwoClick)
        
        #tjm First string field to display the H, S, and V values
        self.cv = StringVar()
        self.info = Label(self, textvariable=self.cv)
        self.info.place(x=color_column, y=y_label)
        
        #tjm second string field to display H, S, and V values
        self.cvTwo = StringVar()
        self.infoTwo = Label(self, textvariable=self.cvTwo)
        self.infoTwo.place(x=color_column, y=y_label+row_height)
        
        #tjm label for associated color terms field
        self.cvThree = StringVar()
        self.infoThree = Label(self, textvariable=self.cvThree)
        self.infoThree.place(x=assoc_column, y=y_label)

        #tjm label for distinguishing color terms field
        self.cvFour = StringVar()
        self.infoFour = Label(self, textvariable=self.cvFour)
        self.infoFour.place(x=dist_column, y=y_label)      
                
        #tjm instruction text for color term assignment prediction function
        self.cvFive =  StringVar()
        self.infoFive = Label(self, textvariable=self.cvFive)
        self.infoFive.place(x=left_column, y=y_label+2*row_height)

        self.display = Text(self, border=1, 
            relief=SUNKEN, width=25, height=self.output_lines)
        self.display.place(x=assoc_column, y=start_height)
        self.display.tag_configure('undistinguished', foreground='dark salmon')
        
        #tjm Added second text window to display color labels
        self.displayTwo = Text(self, border=1, 
            relief=SUNKEN, width=25, height=self.output_lines)
        self.displayTwo.place(x=assoc_column, y=start_height+row_height)
        self.displayTwo.tag_configure('undistinguished', foreground='dark salmon')
        
        #tjm Text field that displays distinction color term for top color
        self.distLabel = Text(self, border=1, 
            relief=SUNKEN, width=25, height=self.output_lines)
        self.distLabel.place(x=dist_column, y=start_height)
        
        #tjm Text field that shows distinction color term for bottom color
        self.distLabelTwo = Text(self, border=1, 
            relief=SUNKEN, width=25, height=self.output_lines)
        self.distLabelTwo.place(x=dist_column, y=start_height+row_height)
        
        #tjm added Entry widget for user to supply a color term
        self.e = Entry(self, bd = 5)
        self.e.bind("<Return>", lambda(event):self.onChooseAssign(self.e.get()))
        self.e.place(x = assoc_column, y=y_label+2*row_height)
        
        #tjm added text window to display result
        self.assignmentResult = Text(self, border = 1,
            relief=SUNKEN, width = 25, height = 2)
        self.assignmentResult.place(x = dist_column, y = y_label+2*row_height)
        
        self.cvThree.set('Associated Color Terms')
        self.cvFour.set('Differentiating Color Terms')
        self.cvFive.set('Test color term to interpret')

        self.update_output()
        self.update_outputTwo()
        self.distAndDisplay()
        
    def distAndDisplay(self):
        hueResultList = self.distinguish(1)
        hueResultListTwo = self.distinguish(2)
        #tjm displays top N choices and confidence ratings in the distLabel text field
        desc = [ '{:<17} {:.3f}\n'.format(hueResultList[i][0], hueResultList[i][1]) for i in range(self.output_lines) ]
        self.distLabel.config(state=NORMAL)
        self.distLabel.delete(1.0, END)
        self.distLabel.insert(END, ''.join(desc))
        self.distLabel.config(state=DISABLED)
        descs = [hueResultList[i][0] for i in range(self.output_lines)]
        
        descTwo = [ '{:<17} {:.3f}\n'.format(hueResultListTwo[i][0], hueResultListTwo[i][1]) for i in range(self.output_lines) ]
        self.distLabelTwo.config(state=NORMAL)
        self.distLabelTwo.delete(1.0, END)
        self.distLabelTwo.insert(END, ''.join(descTwo))
        self.distLabelTwo.config(state=DISABLED)
        descsTwo = [hueResultListTwo[i][0] for i in range(self.output_lines)]

        #tjm the "items" field holds the probability for each color term being used to describe hsv_color
        (h, s, v) = self.hsv_color
        items = self.lux.full_posterior((h * 360, s * 100, v * 100))
        desc = [ '{:<17} {:.3f}\n'.format(items[i][0], items[i][1]) for i in range(self.output_lines) ]

        #tjm displays the HSV values
        self.display.config(state=NORMAL)
        self.display.delete(1.0, END)
        self.display.insert(END, ''.join(desc))
        for i in range(self.output_lines) :
            if items[i][0] not in descs :
                self.display.tag_add('undistinguished', str(i+1) + ".0", str(i+1) + ".23")
        self.display.config(state=DISABLED)    

        #tjm the "itemsTwo" field holds the probability for each color term being used to describe hsc_colorTwo
        (h, s, v) = self.hsv_colorTwo
        itemsTwo = self.lux.full_posterior((h * 360, s * 100, v * 100))
        descTwo = [ '{:<17} {:.3f}\n'.format(itemsTwo[i][0], itemsTwo[i][1]) for i in range(self.output_lines) ]
        self.displayTwo.config(state=NORMAL)
        self.displayTwo.delete(1.0, END)
        self.displayTwo.insert(END, ''.join(descTwo))
        for i in range(self.output_lines) :
            if itemsTwo[i][0] not in descsTwo :
                self.displayTwo.tag_add('undistinguished', str(i+1) + ".0", str(i+1) + ".23")
        self.displayTwo.config(state=DISABLED)    

        self.onChooseAssign(self.e.get())

    def onChoose(self):
      
        news = tkColorChooser.askcolor()
        if news and news[0]:
            ((red,green,blue), hx) = news
            self.hex_color = hx
            self.hsv_color = colorsys.rgb_to_hsv(red/255.0, green/255.0, blue/255.0)
            self.frame.config(bg=hx)
            self.update_output()
            self.distAndDisplay()
            
    #tjm Added second onChoose function for when the second button is clicked
    def onChooseTwo(self):
      
        news = tkColorChooser.askcolor()
        if news and news[0]:
            ((red,green,blue), hx) = news
            self.hex_colorTwo = hx
            self.hsv_colorTwo = colorsys.rgb_to_hsv(red/255.0, green/255.0, blue/255.0)
            self.frameTwo.config(bg=hx)
            self.update_outputTwo()
            self.distAndDisplay()
            
    def onChooseClick(self, event) :
        self.onChoose()

    def onChooseTwoClick(self, event) :
        self.onChooseTwo()
        
    def onChooseAssign(self, colorTerm):
        node = self.lux.all.get(colorTerm)
        if node:
            scoreTop = self.score(node, self.hsv_color, self.hsv_colorTwo)
            scoreNumberTop = scoreTop[1]
            scoreBottom= self.score(node, self.hsv_colorTwo, self.hsv_color)
            scoreNumberBottom = scoreBottom[1]
            totalScoreTop = (scoreNumberTop/(scoreNumberTop+scoreNumberBottom))
            if totalScoreTop > 0.5:
                winner = '{:<17} {:.3f}\n{:<14} {:.6f}'.format('top color!', totalScoreTop, colorTerm, scoreNumberTop)
            else:
                if totalScoreTop < 0.5:
                    winner = '{:<17} {:.3f}\n{:<14} {:.6f}'.format('bottom color!', (1.0 - totalScoreTop),  colorTerm, scoreNumberBottom)
                else:
                    winner = 'Could describe either.\n{:<14f} {:.6f}'.format(colorTerm, scoreNumberTop)
        elif colorTerm :
            winner = 'Unknown term: ' +  colorTerm 
        else :
            winner = ''
            
        self.assignmentResult.config(state=NORMAL)
        self.assignmentResult.delete(1.0, END)
        self.assignmentResult.insert(END, winner)
        self.assignmentResult.config(state=DISABLED)  
    
    def score(self, currentNode, hsvY, hsvZ):
        (hY, sY, vY) = hsvY
        (hZ, sZ, vZ) = hsvZ
        
        hY *= 360
        sY *= 100
        vY *= 100
        hZ *= 360
        sZ *= 100
        vZ *= 100
        
        muHLow = currentNode.dim_models[0].params[0]
        muHHigh = currentNode.dim_models[0].params[3]
        muSLow = currentNode.dim_models[1].params[0]
        muSHigh = currentNode.dim_models[1].params[3]
        muVLow = currentNode.dim_models[2].params[0]
        muVHigh = currentNode.dim_models[2].params[3]
        # mds changed to hY and hZ - never use the unscaled values
        phiHY = currentNode.dim_models[0].phi(hY)
        phiHZ = currentNode.dim_models[0].phi(hZ)
        phiSY = currentNode.dim_models[1].phi(sY)
        phiSZ = currentNode.dim_models[1].phi(sZ)
        phiVY = currentNode.dim_models[2].phi(vY)
        phiVZ = currentNode.dim_models[2].phi(vZ)
 
        # mds added: need to handle hue adjust
        if currentNode.dim_models[0].adjust :
                adjust = True; 
                nhY = atan2(sin(hY*pi/180),cos(hY*pi/180))*180/pi
                nhZ = atan2(sin(hZ*pi/180),cos(hZ*pi/180))*180/pi
        else :
                adjust = False;
                nhY = hY;
                nhZ = hZ;
                
        """
        ([product over opposite dimensions d] phi_d(y) ) *  <== termA
        ([product over other dimensions d] phi_d(y) - <== termB
        [product over all dimensions d] phi_d(z)) <== termC
        """
        termA = 1.0
        termB = 1.0
        termC = phiHZ * phiSZ * phiVZ
        oppSideCase = 0
        #tjm determine which case and calculate appropriate y-but-not-z value
            
        #tjm opposite sides case for hue
        if ((nhY < muHLow) & (muHHigh < nhZ)) | ((nhZ < muHLow) & (muHHigh < nhY)):
            termA *= phiHY
            oppSideCase += 1
        else:
            termB *= phiHY
        #tjm opposite sides case for saturation
        if ((sY < muSLow) & (muSHigh < sZ)) | ((sZ < muSLow) & (muSHigh < sY)):
            termA *= phiSY   
            oppSideCase += 1
        else:
            termB *= phiSY
        #tjm opposite sides case for value
        if ((vY < muVLow) & (muVHigh < vZ)) | ((vZ < muVLow) & (muVHigh < vY)):
                termA *= phiVY 
                oppSideCase +=1
        else:
            termB *= phiVY   
            
        score = termA * (termB - termC)
        if score < 0:
            score = 0
        #mds weight words by availability
        score *= currentNode.availability
        
        return [currentNode.name, score, termA, termB, termC, oppSideCase, adjust, nhY, nhZ, muHLow, muHHigh]
    
    #tjm Method to select color term that describes one color but not the other
    def distinguish(self, choice):        
        
        """tjm process:
        1) go through all color terms
            1a) see if it's an acceptable case
            1b) calculate y-but-not-z-confidence
            1c) store color term name and y-but-not-z-confidence in list
        2) return sorted list
        3) print out top 5 values for sanity check 
        """
        
        #tjm list of color terms and associated y-but-not-z confidence
        hueResults = []
        
        #tjm determine if you're picking a term to describe top color or bottom color
        if choice == 1:
            #tjm loop over all color terms
            for currentNodeChoice in self.lux.all.values(): 
                #mds enable comprehensive debugging reports
                hueResults.append(self.score(currentNodeChoice, self.hsv_color, self.hsv_colorTwo))
        else:
            for currentNodeChoice in self.lux.all.values(): 
                #mds enable comprehensive debugging reports
                hueResults.append(self.score(currentNodeChoice, self.hsv_colorTwo, self.hsv_color))

        total = sum(r[1] for r in hueResults)
        for r in hueResults :
            r[1] /= total
            
        return sorted(hueResults, key = lambda hueResults:hueResults[1], reverse=True)