def _on_mouse_click(self, evt):
        if self.current_node is None:
            return
        for tag in self.current_node.get_tags():
            if (tag.startswith('DataAcquis|TLM') or 
                tag.startswith('DataAcquis|HCS')):
                for well in self.current_node.get_well_ids():
                    image_tag = '%s|Images|%s|%s|%s'%(exp.get_tag_stump(tag, 2),
                                                      exp.get_tag_instance(tag),
                                                      exp.get_tag_timepoint(tag),
                                                      well)
                    urls = meta.get_field(image_tag, [])
                    for url in urls:
                        im = Image.open(url)
                        im.show()
            elif tag.startswith('DataAcquis|FCS'):
                for well in self.current_node.get_well_ids():
                    image_tag = '%s|Images|%s|%s|%s'%(exp.get_tag_stump(tag, 2),
                                                  exp.get_tag_instance(tag),
                                                  exp.get_tag_timepoint(tag),
                                                  well)
                    urls = meta.get_field(image_tag, [])
                    for url in urls:
                        os.startfile(url)
        
##        message = ''
##        for well in sorted(self.current_node.get_well_ids()):
##            message += ', '.join(well)
##            message += '\n'
##        msg = wx.MessageDialog(self, message, caption='Info', style=wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP, pos=(200,200))
##        msg.ShowModal()
##        msg.Destroy()
        
        
        try:
            bench = wx.GetApp().get_bench()
        except: 
            return
        
        # --- Update the Bench view ---
        bench.set_timepoint(self.current_node.get_timepoint())
        bench.taglistctrl.set_selected_protocols(
            [exp.get_tag_protocol(tag) for tag in self.current_node.get_tags()])
        bench.group_checklist.SetCheckedStrings(
            [exp.PlateDesign.get_plate_group(well[0]) 
             for well in self.current_node.get_well_ids()])
        bench.update_plate_groups()
        bench.update_well_selections()
    def remove_harvest_seed_track(self, h_tag):
        """Completely removes all events associated with a harvest_seed (sample transfer) track including the harvest seed coupled event"""
        h_instance = exp.get_tag_instance(h_tag)
        harvest_tp = exp.get_tag_timepoint(h_tag)
        tag_list = [h_tag]

        for s_instance in meta.get_field_instances("Transfer|Seed|HarvestInstance"):
            if meta.get_field("Transfer|Seed|HarvestInstance|%s" % s_instance) == h_instance:
                s_tag = "Transfer|Seed|Wells|%s|%s" % (
                    s_instance,
                    str(harvest_tp + 1),
                )  # coupled seed is always 1 min after from harvest
                for tpnode in self.nodes_by_timepoint[harvest_tp + 1]:
                    if tpnode:
                        if s_tag in tpnode.tags:
                            for c_tag in self.get_children_tags(tpnode, 5):
                                if c_tag.startswith(
                                    "Transfer|Harvest"
                                ):  # in case further harvest-seed is there then make it recursive
                                    self.remove_harvest_seed_track(c_tag)
                                else:
                                    for s_well in meta.get_field(s_tag):
                                        c_wells = meta.get_field(c_tag)
                                        if s_well in c_wells:
                                            c_wells.remove(s_well)
                                            meta.remove_associated_dataacquis_tag([s_well])
                                            if c_wells:  # if at least one other affected well
                                                meta.set_field(c_tag, c_wells)
                                            else:
                                                meta.remove_field(c_tag)  # tag with single well
                                                meta.remove_timeline_attachments(exp.get_tag_timepoint(c_tag))
                            meta.remove_field(h_tag)
                            meta.remove_field(s_tag)
                            meta.remove_harvest_seed_tags(h_instance, s_instance)
    def _on_click(self, evt):
        if self.hover_timepoint is not None:
            try:
                bench = wx.GetApp().get_bench()
            except:
                return
            bench.set_timepoint(self.hover_timepoint)
            bench.update_well_selections()

        if self.curr_note_tag is not None:
            note_type = exp.get_tag_event(self.curr_note_tag)
            timepoint = exp.get_tag_attribute(self.curr_note_tag)
            self.page_counter = exp.get_tag_instance(self.curr_note_tag)
            if exp.get_tag_type(self.curr_note_tag) == "Notes":
                note_dia = NotePad(self, note_type, timepoint, self.page_counter)
                if note_dia.ShowModal() == wx.ID_OK:
                    # Notes|<type>|<timepoint>|<instance> = value
                    meta.set_field(
                        "Notes|%s|%s|%s" % (note_dia.noteType, timepoint, str(self.page_counter)),
                        note_dia.noteDescrip.GetValue(),
                    )
            elif exp.get_tag_type(self.curr_note_tag) == "Attachments":
                attfileTAG = "Attachments|Files|%s|%s" % (timepoint, str(self.page_counter))
                dia = FileListDialog(self, attfileTAG, meta.get_field(attfileTAG, []), None)
                if dia.ShowModal() == wx.ID_OK:
                    f_list = dia.file_list
                    if f_list:
                        meta.set_field(attfileTAG, f_list)
    def find_ancestral_tags(self, node):
        ancestral_tags = []
        for pnode in timeline.reverse_iter_tree(node):
            if pnode:
                for ptag in pnode.tags:
                    if (
                        ptag.startswith("Transfer|Seed")
                        and meta.get_field("Transfer|Seed|HarvestInstance|" + exp.get_tag_instance(ptag)) is not None
                    ):
                        for tpnode in self.nodes_by_timepoint[pnode.get_timepoint() - 1]:
                            if tpnode:
                                for tptag in tpnode.tags:
                                    if exp.get_tag_protocol(tptag) == "Transfer|Harvest|%s" % meta.get_field(
                                        "Transfer|Seed|HarvestInstance|" + exp.get_tag_instance(ptag)
                                    ):
                                        for npnode in timeline.reverse_iter_tree(tpnode):
                                            if npnode:
                                                for nptag in npnode.tags:
                                                    ancestral_tags.append(nptag)
                    else:
                        ancestral_tags.append(ptag)

        return list(reversed(ancestral_tags))
示例#5
0
    def _on_click(self, evt):
        if self.hover_timepoint is not None:
            try:
                bench = wx.GetApp().get_bench()
            except: return
            bench.set_timepoint(self.hover_timepoint)
            bench.update_well_selections()
	
	if self.current_ntag is not None:
	    note_type = exp.get_tag_event(self.current_ntag)	    
	    timepoint = exp.get_tag_attribute(self.current_ntag)
	    self.page_counter = exp.get_tag_instance(self.current_ntag)
	    
	    
	    note_dia = NotePad(self, note_type, timepoint, self.page_counter)
	    if note_dia.ShowModal() == wx.ID_OK:
		    # Notes|<type>|<timepoint>|<instance> = value
		meta.set_field('Notes|%s|%s|%s' %(note_dia.noteType, timepoint, str(self.page_counter)), note_dia.noteDescrip.GetValue())   	    
示例#6
0
    def _on_click(self, evt):
        if self.hover_timepoint is not None:
            try:
                bench = wx.GetApp().get_bench()
            except: return
            bench.set_timepoint(self.hover_timepoint)
            bench.update_well_selections()
	
	if self.current_ntag is not None:
	    note_type = exp.get_tag_event(self.current_ntag)	    
	    timepoint = exp.get_tag_attribute(self.current_ntag)
	    self.page_counter = exp.get_tag_instance(self.current_ntag)
	    
	    
	    note_dia = NotePad(self, note_type, timepoint, self.page_counter)
	    if note_dia.ShowModal() == wx.ID_OK:
		    # Notes|<type>|<timepoint>|<instance> = value
		meta.set_field('Notes|%s|%s|%s' %(note_dia.noteType, timepoint, str(self.page_counter)), note_dia.noteDescrip.GetValue())   	    
    def _on_paint(self, evt=None):
        '''Handler for paint events.
        '''
        if self.nodes_by_timepoint == {}:
            evt.Skip()
            return

        t0 = time()
        PAD = self.PAD + self.NODE_R
        NODE_R = self.NODE_R
        MIN_X_GAP = self.MIN_X_GAP
        MIN_Y_GAP = self.MIN_Y_GAP
        FLASK_GAP = self.FLASK_GAP
        MAX_TIMEPOINT = self.timepoints[0]
        timepoints = self.timepoints
        nodes_by_tp = self.nodes_by_timepoint
        self.current_node = None           # Node with the mouse over it
        w_win, h_win = (float(self.Size[0]), float(self.Size[1]))
                    
        if self.time_x:
            if timepoints[0] == 0:
                px_per_time = 1
            else:
                px_per_time = max((w_win - PAD * 2 - FLASK_GAP) / MAX_TIMEPOINT,
                                  MIN_X_GAP)
                
        if len(nodes_by_tp) == 2:
            x_gap = 1
        else:
            # calculate the number of pixels to separate each generation timepoint
            x_gap = max(MIN_X_GAP, 
                         (w_win - PAD * 2 - FLASK_GAP) / (len(nodes_by_tp) - 2))
            
        if len(nodes_by_tp[timepoints[0]]) == 1:
            y_gap = MIN_Y_GAP
        else:
            # calcuate the minimum number of pixels to separate nodes on the y axis
            y_gap = max(MIN_Y_GAP, 
                        (h_win - PAD * 2) / (len(nodes_by_tp[MAX_TIMEPOINT]) - 1))
                        
        nodeY = {}  # Store y coords of children so we can calculate where to draw the parents
        Y = PAD
        X = w_win - PAD
        
        dc = wx.PaintDC(self)
        dc.Clear()
        dc.BeginDrawing()
        #dc.SetPen(wx.Pen("BLACK",1))
        
        def hover(mouse_pos, node_pos, node_r):
            '''returns whether the mouse is hovering over a node
            mouse_pos - the mouse position
            node_pos - the node position
            node_r - the node radius
            '''
            if mouse_pos is None:
                return False
            MX,MY = mouse_pos
            X,Y = node_pos
            return (X - node_r < MX < X + node_r and 
                    Y - node_r < MY < Y + node_r)

        # Iterate from leaf nodes up to the root, and draw R->L, Top->Bottom
        for i, t in enumerate(timepoints):
            if t == -1:
                X = PAD
            elif self.time_x:
                X = PAD + FLASK_GAP + t * px_per_time
                x_gap = PAD + FLASK_GAP + timepoints[i-1] * px_per_time - X
            else:
                X = PAD + FLASK_GAP + (len(timepoints) - i - 2) * x_gap
            
            # NO EVENTS. JUST DRAW THE STOCK, CENTERED.
            if len(nodes_by_tp) == 1:
                X = w_win / 2
                Y = h_win / 2
                if hover(self.cursor_pos, (X,Y), self.NODE_R): 
                    dc.SetBrush(wx.Brush('#FFFFAA'))
                    self.current_node = nodes_by_tp.values()[t][0]
                else:
                    dc.SetBrush(wx.Brush('#FAF9F7'))
                    self.current_node = None
                dc.DrawRectangle(X-NODE_R, Y-NODE_R, NODE_R*2, NODE_R*2)
##                dc.DrawText(str(nodes_by_tp[t][0].get_timepoint()), X, Y+NODE_R)
                
            # LEAF NODES
            elif i == 0:
                for node in nodes_by_tp[t]:
                    empty_path = False # whether this path follows a harvesting
                    if len(node.get_tags()) > 0:
                        # Event occurred
                        dc.SetBrush(wx.Brush('YELLOW'))
                    else:
                        # No event
                        dc.SetBrush(wx.Brush('WHITE'))
                        if 'CellTransfer|Harvest' in [exp.get_tag_stump(ptag, 2)
                                                      for pnode in timeline.reverse_iter_tree(node) if pnode
                                                      for ptag in pnode.tags]:
                            empty_path = True

                    if hover(self.cursor_pos, (X,Y), self.NODE_R):
                        # MouseOver
                        dc.SetPen(wx.Pen('#000000', 3))
                        self.current_node = node
                    else:
                        # No MouseOver
                        dc.SetPen(wx.Pen('#000000', 1))
                    
                    if not empty_path:
                        dc.DrawCircle(X, Y, NODE_R)
##                        dc.DrawText(str(node.get_tags()), X, Y+NODE_R)
                    nodeY[node.id] = Y
                    Y += y_gap
                    
            # INTERNAL NODES
            else:
                for node in nodes_by_tp[t]:
                    empty_path = False # whether this path follows a harvesting
                    ys = []
                    for child in node.get_children():
                        ys.append(nodeY[child.id])
                    Y = (min(ys) + max(ys)) / 2

                    if len(node.get_tags()) > 0:
                        # Event occurred
                        dc.SetBrush(wx.Brush('YELLOW'))
                    else:
                        # No event
                        dc.SetBrush(wx.Brush('WHITE'))
                        if 'CellTransfer|Harvest' in [exp.get_tag_stump(ptag, 2)
                                                      for pnode in timeline.reverse_iter_tree(node) if pnode
                                                      for ptag in pnode.tags]:
                            empty_path = True

                    if hover(self.cursor_pos, (X,Y), self.NODE_R):
                        # MouseOver
                        dc.SetPen(wx.Pen(wx.BLACK, 3))
                        self.current_node = node
                    else:
                        # No MouseOver
                        dc.SetPen(wx.Pen(wx.BLACK, 1))
                    
                    if t == -1:
                        dc.DrawRectangle(X-NODE_R, Y-NODE_R, NODE_R*2, NODE_R*2)
                    else:
                        if not empty_path:
                            dc.DrawCircle(X, Y, NODE_R)
##                            dc.DrawText(str(node.get_tags()), X, Y+NODE_R)
                        
                    # DRAW LINES CONNECTING THIS NODE TO ITS CHILDREN
                    dc.SetBrush(wx.Brush('#FAF9F7'))
                    dc.SetPen(wx.Pen(wx.BLACK, 1))
                    harvest_tag = False
                    for tag in node.get_tags():
                        if tag.startswith('CellTransfer|Harvest'):
                            harvest_tag = tag
                    for child in node.get_children():
                        if t == -1:
                            if self.time_x:
                                dc.DrawLine(X + NODE_R, Y, 
                                            X + FLASK_GAP + px_per_time * timepoints[i-1] - NODE_R ,nodeY[child.id])
                            else:
                                dc.DrawLine(X + NODE_R, Y, 
                                            X + FLASK_GAP - NODE_R ,nodeY[child.id])
                        else:
                            if harvest_tag:
                                # TODO: improve performance by caching reseed 
                                #       events from the previous timepoint
                                for nn in nodes_by_tp[timepoints[i-1]]:
                                    for tag in nn.get_tags():
                                        if (tag.startswith('CellTransfer|Seed') and 
                                            meta.get_field('CellTransfer|Seed|HarvestInstance|'+exp.get_tag_instance(tag)) == exp.get_tag_instance(harvest_tag)):
                                            dc.SetPen(wx.Pen('BLACK', 1, wx.SHORT_DASH))
                                            dc.DrawLine(X + NODE_R, Y, 
                                                        X + x_gap - NODE_R ,nodeY[nn.id])
                            else:
                                if not empty_path:
                                    dc.SetPen(wx.Pen(wx.BLACK, 1))
                                    dc.DrawLine(X + NODE_R, Y, 
                                                X + x_gap - NODE_R,
                                                nodeY[child.id])
                    nodeY[node.id] = Y
        dc.EndDrawing()
示例#8
0
    def _on_paint(self, evt=None):
        '''Handler for paint events.
        '''
        if self.nodes_by_timepoint == {}:
            evt.Skip()
            return	

        t0 = time()
        PAD = self.PAD + self.NODE_R
        NODE_R = self.NODE_R
	SM_NODE_R = self.SM_NODE_R 
        MIN_X_GAP = self.MIN_X_GAP
        MIN_Y_GAP = self.MIN_Y_GAP
        FLASK_GAP = self.FLASK_GAP
        MAX_TIMEPOINT = self.timepoints[0]
        timepoints = self.timepoints
        nodes_by_tp = self.nodes_by_timepoint
        self.current_node = None           # Node with the mouse over it
        w_win, h_win = (float(self.Size[0]), float(self.Size[1]))
	
        if self.time_x:
            if timepoints[0] == 0:
                px_per_time = 1
            else:
                px_per_time = max((w_win - PAD * 2 - FLASK_GAP) / MAX_TIMEPOINT,
                                  MIN_X_GAP)
	else:
	    px_per_time = 1
                
        if len(nodes_by_tp) == 2:
            x_gap = 1
        else:
            # calculate the number of pixels to separate each generation timepoint
            x_gap = max(MIN_X_GAP, 
                         (w_win - PAD * 2 - FLASK_GAP) / (len(nodes_by_tp) - 2))
            
        if len(nodes_by_tp[timepoints[0]]) == 1:
            y_gap = MIN_Y_GAP
        else:
            # calcuate the minimum number of pixels to separate nodes on the y axis
            y_gap = max(MIN_Y_GAP, 
                        (h_win - PAD * 2) / (len(nodes_by_tp[MAX_TIMEPOINT]) - 1))
                        
        nodeY = {}  # Store y coords of children so we can calculate where to draw the parents
        Y = PAD
        X = w_win - PAD
        
        dc = wx.BufferedPaintDC(self)
        dc.Clear()
        dc.BeginDrawing()
        #dc.SetPen(wx.Pen("BLACK",1))
        
        def hover(mouse_pos, node_pos, node_r):
            '''returns whether the mouse is hovering over a node
            mouse_pos - the mouse position
            node_pos - the node position
            node_r - the node radius
            '''
            if mouse_pos is None:
                return False
            MX,MY = mouse_pos
            X,Y = node_pos
            return (X - node_r < MX < X + node_r and 
                    Y - node_r < MY < Y + node_r)	
	

        # Iterate from leaf nodes up to the root, and draw R->L, Top->Bottom
        for i, t in enumerate(timepoints):
            if t == -1:  # for the root node which is not shown
                X = PAD
            elif self.time_x:
                X = PAD + FLASK_GAP + t * px_per_time
                x_gap = PAD + FLASK_GAP + timepoints[i-1] * px_per_time - X
            else:
                X = PAD + FLASK_GAP + (len(timepoints) - i - 2) * x_gap
		
	    # Draw longitudinal time lines
	    if t != -1:
		dc.SetPen(wx.Pen('#E1E2ED', 1, wx.DOT))
		dc.DrawLine(X, 0, X, h_win)	    
            
            # LEAF NODES
            if i == 0:
                for node in sorted(nodes_by_tp[t], key=self.order_nodes):
		    ancestor_tags = self.get_ancestral_tags(node)	
		    node_tags = node.get_tags()
		    stateRGB = meta.getStateRGB([tags for tags in reversed(ancestor_tags)]+node_tags)# reverse the ancestal line so that it become progeny + curr node			    
		    if node_tags:
			eventRGB = meta.getEventRGB(node_tags[0]) #get all event tags for the passed node and returns the colour associated with the last event** Need to change
		    else:
			eventRGB = (255, 255, 255, 100)
		   
                    empty_path = False # whether this path follows a harvesting
		    event_status = False # whether any event occured to this node		    
		    
                    if len(node.get_tags()) > 0:
                        # Event occurred
			dc.SetBrush(wx.Brush(eventRGB))
			dc.SetPen(wx.Pen(stateRGB, 3))
			event_status = True
			
                    else:
                        # No event
			if eventRGB == (255,255,255,100) and stateRGB == (255,255,255,100):
			    dc.SetBrush(wx.Brush(wx.WHITE))
			    dc.SetPen(wx.Pen(wx.WHITE))	
                        if 'CellTransfer|Harvest' in self.get_ancestral_tags(node):
                            empty_path = True

                    if hover(self.cursor_pos, (X,Y), self.NODE_R):
                        # MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 1))
			    self.current_node = node
                    else:
                        # No MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 3))
                    
                    if not empty_path and event_status:
			#dc.DrawCircle(X, Y, NODE_R)
			#evt_categories = list(set([exp.get_tag_stump(tag, 1) for tag in node.get_tags()]))
			#if all(evt_categories[0] == cat and cat == 'DataAcquis' for cat in evt_categories):
			if 'CellTransfer|Seed|StockInstance' in node_tags:
			    event = 'Stock'
			else:
			    event = exp.get_tag_event(node_tags[0])
			
			dc.DrawBitmap(meta.getEventIcon(16.0, event), X - 16.0 / 2.0, Y - 16.0 / 2.0)
##                      dc.DrawText(str(node.get_tags()), X, Y+NODE_R)
                    nodeY[node.id] = Y
                    Y += y_gap
                    
            # INTERNAL NODES
            else:
                for node in sorted(nodes_by_tp[t], key=self.order_nodes):
		    ancestor_tags = self.get_ancestral_tags(node)
		    children_tags = self.get_children_tags(node)
		    node_tags = node.get_tags()
		    stateRGB = meta.getStateRGB([tags for tags in reversed(ancestor_tags)]+node_tags)# reverse the ancestal line so that it become progeny + curr node			    
		    if node_tags:
			eventRGB = meta.getEventRGB(node_tags[0]) #get all event tags for the passed node and returns the colour associated with the last event** Need to change
		    else:
			eventRGB = (255, 255, 255, 100)
		
                    empty_path = False # whether this path follows a harvesting
		    event_status = False # whether this node has event
		    children_status = False # whether the children nodes have any events associated
		    
		    if children_tags:
			children_status = True
		    
                    ys = []
                    for child in node.get_children():
                        ys.append(nodeY[child.id])
                    Y = (min(ys) + max(ys)) / 2
		    
                    if len(node.get_tags()) > 0:
			#Event occurred
                        dc.SetBrush(wx.Brush(eventRGB))
			dc.SetPen(wx.Pen(stateRGB, 3))
			event_status = True			
                    else:
			#No event
			if eventRGB == (255,255,255,100) and stateRGB == (255,255,255,100):
			    dc.SetBrush(wx.Brush(wx.WHITE))
			    dc.SetPen(wx.Pen(wx.WHITE))
			else:
			    if children_status:
				#dc.SetBrush(wx.Brush(wx.BLACK))
				#dc.SetPen(wx.Pen(wx.BLACK))
				dc.SetBrush(wx.Brush('#D1CDCF'))
				dc.SetPen(wx.Pen('#D1CDCF'))
			    else:
				dc.SetBrush(wx.Brush(wx.WHITE))
				dc.SetPen(wx.Pen(wx.WHITE))			    
			    
			if 'CellTransfer|Harvest' in self.get_ancestral_tags(node):
			    empty_path = True
		
                    if hover(self.cursor_pos, (X,Y), self.NODE_R):
                        # MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 1))
			    self.current_node = node                        
			    self.SetToolTipString(self.ShowTooltipsInfo())
                    else:
                        # No MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 3))
                    
                    #if t == -1:
                        #dc.DrawRectangle(X-NODE_R, Y-NODE_R, NODE_R*2, NODE_R*2)
                    #else:
		    if not empty_path:
			if event_status:
			    if (node_tags[0].startswith('CellTransfer|Seed') and 
				        meta.get_field('CellTransfer|Seed|StockInstance|'+exp.get_tag_instance(node_tags[0])) is not None):
				event = 'Stock'
			    else:
				event = exp.get_tag_event(node_tags[0])
			    #dc.DrawCircle(X, Y, NODE_R)
			    #dc.SetPen(wx.Pen('BLACK'))
			    #dc.DrawCircle(X, Y, NODE_R-3/2)
			    dc.DrawBitmap(meta.getEventIcon(16.0, event), X - 16.0 / 2.0, Y - 16.0 / 2.0)
				
			else:
			    #dc.DrawCircle(X-NODE_R,Y, SM_NODE_R) # draws the node slightly left hand side on the furcation point
			    #dc.SetBrush(wx.Brush(stateRGB))
			    dc.DrawCircle(X,Y, SM_NODE_R)
			#dc.DrawText(str(node.get_tags()), X, Y+NODE_R)
                        
                    # DRAW LINES CONNECTING THIS NODE TO ITS CHILDREN
                    dc.SetBrush(wx.Brush('#FAF9F7'))
                    #dc.SetPen(wx.Pen(wx.BLACK, 1))
		    dc.SetPen(wx.Pen('#D1CDCF'))
		    #dc.SetPen(wx.Pen(stateRGB))
                    harvest_tag = False
                    for tag in node.get_tags():
                        if tag.startswith('CellTransfer|Harvest'):
                            harvest_tag = tag
		    # for children of this node check whether furhter event had occured to them if not do not draw the line 
                    for child in node.get_children():
			if harvest_tag:
			    # TODO: improve performance by caching reseed 
			    #       events from the previous timepoint
			    for nn in nodes_by_tp[timepoints[i-1]]:
				for tag in nn.get_tags():
				    if (tag.startswith('CellTransfer|Seed') and 
				        meta.get_field('CellTransfer|Seed|HarvestInstance|'+exp.get_tag_instance(tag)) == exp.get_tag_instance(harvest_tag)):
					dc.SetPen(wx.Pen('#948BB3', 1, wx.SHORT_DASH))
					dc.DrawLine(X + NODE_R, Y, 
				                    X + x_gap - NODE_R ,nodeY[nn.id])
			else:
			    if not empty_path:
				if event_status:
				    if children_status:
					dc.DrawLine(X + NODE_R, Y, 
					            X + x_gap - NODE_R, nodeY[child.id])	
				else:
				    if children_status and stateRGB != (255,255,255,100):
					    dc.SetPen(wx.Pen('#D1CDCF'))
					    #dc.SetPen(wx.Pen(stateRGB))
					    dc.DrawLine(X, Y,
						        X + x_gap, nodeY[child.id])
			
                    nodeY[node.id] = Y
		    
		    
	#if self.timepoint_cursor is not None:  # BUG: New addition of 24hr will not work, i.e. the timeline cant hover over no event time zone****
	    #timepoints = meta.get_timeline().get_unique_timepoints()	
	    #ti = bisect.bisect_left(timepoints, self.timepoint_cursor)
	    #time_interval =  timepoints[ti]-timepoints[ti-1]
	    ##according to the time interval calculate the px per time.
	    ##px_per_time = max((w_win - PAD * 2 - FLASK_GAP) / MAX_TIMEPOINT,
			                      ##MIN_X_GAP)	
	    #px_per_ti = (w_win - PAD * 2 - FLASK_GAP) /(len(timepoints)-1)
	    #adjusted_factor = px_per_ti/time_interval
	   
	    #X = PAD + FLASK_GAP +px_per_ti*(ti-1)+(self.timepoint_cursor - timepoints[ti-1])* adjusted_factor
	   
	    #dc.SetPen(wx.Pen(wx.BLACK, 3))
	    #dc.DrawLine(X, 0, X, h_win)
	  
        dc.EndDrawing()
    def _on_mouse_click(self, evt):
        if self.current_node is None:
            return
        for tag in self.current_node.get_tags():
            if tag.startswith("DataAcquis|TLM") or tag.startswith("DataAcquis|HCS"):
                for well in self.current_node.get_well_ids():
                    image_tag = "%s|Images|%s|%s|%s" % (
                        exp.get_tag_stump(tag, 2),
                        exp.get_tag_instance(tag),
                        exp.get_tag_timepoint(tag),
                        well,
                    )
                    urls = meta.get_field(image_tag, [])
                    image_viewer_path = ""
                    if os.path.isfile("C:\Program Files\ImageJ\ImageJ.exe"):
                        ImageJPath = "C:\Program Files\ImageJ\ImageJ.exe"
                        subprocess.Popen("%s %s" % (ImageJPath, " ".join(urls)))
                    else:
                        dlg = wx.lib.dialogs.ScrolledMessageDialog(
                            self,
                            str("\n".join(urls)),
                            "ERROR!! ImageJ was not found in C\Program Files directory to show following images",
                        )
                        dlg.ShowModal()
                        return
                        # for url in urls:
                        # im = Image.open(url)
                        # im.show()
                        ##TODO: make it Try with ImageJ first then Exception is Image.open(url)
                        # ImageJPath = r'C:\Program Files\ImageJ\ImageJ'
                        # subprocess.Popen("%s %s" % (ImageJPath, url))

            elif tag.startswith("DataAcquis|FCS"):
                for well in self.current_node.get_well_ids():
                    image_tag = "%s|Images|%s|%s|%s" % (
                        exp.get_tag_stump(tag, 2),
                        exp.get_tag_instance(tag),
                        exp.get_tag_timepoint(tag),
                        well,
                    )
                    urls = meta.get_field(image_tag, [])
                    for url in urls:
                        os.startfile(url)

        # print self.current_node.get_well_ids()
        # print self.current_node.get_parent()

        ##        message = ''
        ##        for well in sorted(self.current_node.get_well_ids()):
        ##            message += ', '.join(well)
        ##            message += '\n'
        ##        msg = wx.MessageDialog(self, message, caption='Info', style=wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP, pos=(200,200))
        ##        msg.ShowModal()
        ##        msg.Destroy()

        try:
            bench = wx.GetApp().get_bench()
        except:
            return

        # --- Update the Bench view ---
        bench.set_timepoint(self.current_node.get_timepoint())
        bench.taglistctrl.set_selected_protocols([exp.get_tag_protocol(tag) for tag in self.current_node.get_tags()])
        bench.group_checklist.SetCheckedStrings(
            [exp.PlateDesign.get_plate_group(well[0]) for well in self.current_node.get_well_ids()]
        )
        bench.update_plate_groups()
        bench.update_well_selections()

        try:
            exptsettings = wx.GetApp().get_exptsettings()
        except:
            return
        # -- Update the expt setting/metadata view --#
        exptsettings.OnLeafSelect()
        if self.current_node.get_tags():
            exptsettings.ShowInstance(self.current_node.get_tags()[0])

        ancestors = [
            exp.get_tag_stump(ptag, 2)
            for pnode in timeline.reverse_iter_tree(self.current_node)
            if pnode
            for ptag in pnode.tags
        ]
示例#10
0
    def _on_paint(self, evt=None):
        '''Handler for paint events.
        '''
        if self.nodes_by_timepoint == {}:
            evt.Skip()
            return	

        t0 = time()
        PAD = self.PAD + self.NODE_R
        NODE_R = self.NODE_R
	SM_NODE_R = self.SM_NODE_R 
        MIN_X_GAP = self.MIN_X_GAP
        MIN_Y_GAP = self.MIN_Y_GAP
        FLASK_GAP = self.FLASK_GAP
        MAX_TIMEPOINT = self.timepoints[0]
        timepoints = self.timepoints
        nodes_by_tp = self.nodes_by_timepoint
        self.current_node = None           # Node with the mouse over it
        w_win, h_win = (float(self.Size[0]), float(self.Size[1]))
	
        if self.time_x:
            if timepoints[0] == 0:
                px_per_time = 1
            else:
                px_per_time = max((w_win - PAD * 2 - FLASK_GAP) / MAX_TIMEPOINT,
                                  MIN_X_GAP)
	else:
	    px_per_time = 1
                
        if len(nodes_by_tp) == 2:
            x_gap = 1
        else:
            # calculate the number of pixels to separate each generation timepoint
            x_gap = max(MIN_X_GAP, 
                         (w_win - PAD * 2 - FLASK_GAP) / (len(nodes_by_tp) - 2))
            
        if len(nodes_by_tp[timepoints[0]]) == 1:
            y_gap = MIN_Y_GAP
        else:
            # calcuate the minimum number of pixels to separate nodes on the y axis
            y_gap = max(MIN_Y_GAP, 
                        (h_win - PAD * 2) / (len(nodes_by_tp[MAX_TIMEPOINT]) - 1))
                        
        nodeY = {}  # Store y coords of children so we can calculate where to draw the parents
        Y = PAD
        X = w_win - PAD
        
        dc = wx.BufferedPaintDC(self)
        dc.Clear()
        dc.BeginDrawing()
        #dc.SetPen(wx.Pen("BLACK",1))
        
        def hover(mouse_pos, node_pos, node_r):
            '''returns whether the mouse is hovering over a node
            mouse_pos - the mouse position
            node_pos - the node position
            node_r - the node radius
            '''
            if mouse_pos is None:
                return False
            MX,MY = mouse_pos
            X,Y = node_pos
            return (X - node_r < MX < X + node_r and 
                    Y - node_r < MY < Y + node_r)	
	

        # Iterate from leaf nodes up to the root, and draw R->L, Top->Bottom
        for i, t in enumerate(timepoints):
            if t == -1:  # for the root node which is not shown
                X = PAD
            elif self.time_x:
                X = PAD + FLASK_GAP + t * px_per_time
                x_gap = PAD + FLASK_GAP + timepoints[i-1] * px_per_time - X
            else:
                X = PAD + FLASK_GAP + (len(timepoints) - i - 2) * x_gap
		
	    # Draw longitudinal time lines
	    if t != -1:
		dc.SetPen(wx.Pen('#E1E2ED', 1, wx.DOT))
		dc.DrawLine(X, 0, X, h_win)	    
            
            # LEAF NODES
            if i == 0:
                for node in sorted(nodes_by_tp[t], key=self.order_nodes):
		    ancestor_tags = self.get_ancestral_tags(node)	
		    node_tags = node.get_tags()
		    stateRGB = meta.getStateRGB([tags for tags in reversed(ancestor_tags)]+node_tags)# reverse the ancestal line so that it become progeny + curr node			    
		    if node_tags:
			eventRGB = meta.getEventRGB(node_tags[0]) #get all event tags for the passed node and returns the colour associated with the last event** Need to change
		    else:
			eventRGB = (255, 255, 255, 100)
		   
                    empty_path = False # whether this path follows a harvesting
		    event_status = False # whether any event occured to this node		    
		    
                    if len(node.get_tags()) > 0:
                        # Event occurred
			dc.SetBrush(wx.Brush(eventRGB))
			dc.SetPen(wx.Pen(stateRGB, 3))
			event_status = True
			
                    else:
                        # No event
			if eventRGB == (255,255,255,100) and stateRGB == (255,255,255,100):
			    dc.SetBrush(wx.Brush(wx.WHITE))
			    dc.SetPen(wx.Pen(wx.WHITE))	
                        if 'CellTransfer|Harvest' in self.get_ancestral_tags(node):
                            empty_path = True

                    if hover(self.cursor_pos, (X,Y), self.NODE_R):
                        # MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 1))
			    self.current_node = node
                    else:
                        # No MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 3))
                    
                    if not empty_path and event_status:
			#dc.DrawCircle(X, Y, NODE_R)
			#evt_categories = list(set([exp.get_tag_stump(tag, 1) for tag in node.get_tags()]))
			#if all(evt_categories[0] == cat and cat == 'DataAcquis' for cat in evt_categories):
			if 'CellTransfer|Seed|StockInstance' in node_tags:
			    event = 'Stock'
			else:
			    event = exp.get_tag_event(node_tags[0])
			
			dc.DrawBitmap(meta.getEventIcon(16.0, event), X - 16.0 / 2.0, Y - 16.0 / 2.0)
##                      dc.DrawText(str(node.get_tags()), X, Y+NODE_R)
                    nodeY[node.id] = Y
                    Y += y_gap
                    
            # INTERNAL NODES
            else:
                for node in sorted(nodes_by_tp[t], key=self.order_nodes):
		    ancestor_tags = self.get_ancestral_tags(node)
		    children_tags = self.get_children_tags(node)
		    node_tags = node.get_tags()
		    stateRGB = meta.getStateRGB([tags for tags in reversed(ancestor_tags)]+node_tags)# reverse the ancestal line so that it become progeny + curr node			    
		    if node_tags:
			eventRGB = meta.getEventRGB(node_tags[0]) #get all event tags for the passed node and returns the colour associated with the last event** Need to change
		    else:
			eventRGB = (255, 255, 255, 100)
		
                    empty_path = False # whether this path follows a harvesting
		    event_status = False # whether this node has event
		    children_status = False # whether the children nodes have any events associated
		    
		    if children_tags:
			children_status = True
		    
                    ys = []
                    for child in node.get_children():
                        ys.append(nodeY[child.id])
                    Y = (min(ys) + max(ys)) / 2
		    
                    if len(node.get_tags()) > 0:
			#Event occurred
                        dc.SetBrush(wx.Brush(eventRGB))
			dc.SetPen(wx.Pen(stateRGB, 3))
			event_status = True			
                    else:
			#No event
			if eventRGB == (255,255,255,100) and stateRGB == (255,255,255,100):
			    dc.SetBrush(wx.Brush(wx.WHITE))
			    dc.SetPen(wx.Pen(wx.WHITE))
			else:
			    if children_status:
				#dc.SetBrush(wx.Brush(wx.BLACK))
				#dc.SetPen(wx.Pen(wx.BLACK))
				dc.SetBrush(wx.Brush('#D1CDCF'))
				dc.SetPen(wx.Pen('#D1CDCF'))
			    else:
				dc.SetBrush(wx.Brush(wx.WHITE))
				dc.SetPen(wx.Pen(wx.WHITE))			    
			    
			if 'CellTransfer|Harvest' in self.get_ancestral_tags(node):
			    empty_path = True
		
                    if hover(self.cursor_pos, (X,Y), self.NODE_R):
                        # MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 1))
			    self.current_node = node                        
			    self.SetToolTipString(self.ShowTooltipsInfo())
                    else:
                        # No MouseOver
			if event_status:
			    dc.SetPen(wx.Pen(stateRGB, 3))
                    
                    #if t == -1:
                        #dc.DrawRectangle(X-NODE_R, Y-NODE_R, NODE_R*2, NODE_R*2)
                    #else:
		    if not empty_path:
			if event_status:
			    if (node_tags[0].startswith('CellTransfer|Seed') and 
				        meta.get_field('CellTransfer|Seed|StockInstance|'+exp.get_tag_instance(node_tags[0])) is not None):
				event = 'Stock'
			    else:
				event = exp.get_tag_event(node_tags[0])
			    #dc.DrawCircle(X, Y, NODE_R)
			    #dc.SetPen(wx.Pen('BLACK'))
			    #dc.DrawCircle(X, Y, NODE_R-3/2)
			    dc.DrawBitmap(meta.getEventIcon(16.0, event), X - 16.0 / 2.0, Y - 16.0 / 2.0)
				
			else:
			    #dc.DrawCircle(X-NODE_R,Y, SM_NODE_R) # draws the node slightly left hand side on the furcation point
			    #dc.SetBrush(wx.Brush(stateRGB))
			    dc.DrawCircle(X,Y, SM_NODE_R)
			#dc.DrawText(str(node.get_tags()), X, Y+NODE_R)
                        
                    # DRAW LINES CONNECTING THIS NODE TO ITS CHILDREN
                    dc.SetBrush(wx.Brush('#FAF9F7'))
                    #dc.SetPen(wx.Pen(wx.BLACK, 1))
		    dc.SetPen(wx.Pen('#D1CDCF'))
		    #dc.SetPen(wx.Pen(stateRGB))
                    harvest_tag = False
                    for tag in node.get_tags():
                        if tag.startswith('CellTransfer|Harvest'):
                            harvest_tag = tag
		    # for children of this node check whether furhter event had occured to them if not do not draw the line 
                    for child in node.get_children():
			if harvest_tag:
			    # TODO: improve performance by caching reseed 
			    #       events from the previous timepoint
			    for nn in nodes_by_tp[timepoints[i-1]]:
				for tag in nn.get_tags():
				    if (tag.startswith('CellTransfer|Seed') and 
				        meta.get_field('CellTransfer|Seed|HarvestInstance|'+exp.get_tag_instance(tag)) == exp.get_tag_instance(harvest_tag)):
					dc.SetPen(wx.Pen('#948BB3', 1, wx.SHORT_DASH))
					dc.DrawLine(X + NODE_R, Y, 
				                    X + x_gap - NODE_R ,nodeY[nn.id])
			else:
			    if not empty_path:
				if event_status:
				    if children_status:
					dc.DrawLine(X + NODE_R, Y, 
					            X + x_gap - NODE_R, nodeY[child.id])	
				else:
				    if children_status and stateRGB != (255,255,255,100):
					    dc.SetPen(wx.Pen('#D1CDCF'))
					    #dc.SetPen(wx.Pen(stateRGB))
					    dc.DrawLine(X, Y,
						        X + x_gap, nodeY[child.id])
			
                    nodeY[node.id] = Y
		    
		    
	#if self.timepoint_cursor is not None:  # BUG: New addition of 24hr will not work, i.e. the timeline cant hover over no event time zone****
	    #timepoints = meta.get_timeline().get_unique_timepoints()	
	    #ti = bisect.bisect_left(timepoints, self.timepoint_cursor)
	    #time_interval =  timepoints[ti]-timepoints[ti-1]
	    ##according to the time interval calculate the px per time.
	    ##px_per_time = max((w_win - PAD * 2 - FLASK_GAP) / MAX_TIMEPOINT,
			                      ##MIN_X_GAP)	
	    #px_per_ti = (w_win - PAD * 2 - FLASK_GAP) /(len(timepoints)-1)
	    #adjusted_factor = px_per_ti/time_interval
	   
	    #X = PAD + FLASK_GAP +px_per_ti*(ti-1)+(self.timepoint_cursor - timepoints[ti-1])* adjusted_factor
	   
	    #dc.SetPen(wx.Pen(wx.BLACK, 3))
	    #dc.DrawLine(X, 0, X, h_win)
	  
        dc.EndDrawing()
    def _on_mouse_click(self, evt):
        if self.current_node is None:
            return
        # first check whehter the tag is Harvest if so call the method.
        # self.remove_harvest_seed_track(self.current_node.tags[0])

        # meta.remove_field(ctags)
        # --- Update the Bench view ---
        try:
            bench = wx.GetApp().get_bench()
        except:
            return

        bench.selected_harvest_inst = self.current_node.tags[0]
        bench.set_timepoint(self.current_node.get_timepoint())
        bench.taglistctrl.set_selected_protocols([exp.get_tag_protocol(tag) for tag in self.current_node.get_tags()])
        bench.group_checklist.SetCheckedStrings(
            [exp.PlateDesign.get_plate_group(well[0]) for well in self.current_node.get_well_ids()]
        )
        bench.update_plate_groups()
        bench.update_well_selections()
        bench.del_evt_button.Enable()

        # -- Update the expt setting/metadata view --#
        try:
            exptsettings = wx.GetApp().get_exptsettings()
        except:
            return

        exptsettings.OnLeafSelect()
        if self.current_node.get_tags():
            tag = self.current_node.get_tags()[
                0
            ]  # TO DO: if multiple event tag are there need to itterate through the list
            if (
                meta.get_field("Transfer|Seed|HarvestInstance|" + exp.get_tag_instance(tag)) is None
                or exp.get_tag_event(tag) is "Harvest"
            ):
                exptsettings.ShowInstance(tag)

                # -- show the data url list --- #
        data_acquis = False

        for tag in self.current_node.get_tags():
            if tag.startswith("DataAcquis"):
                data_acquis = True
                break

        if data_acquis:
            dia = DataLinkListDialog(
                self,
                self.current_node.get_well_ids(),
                self.current_node.get_timepoint(),
                self.find_ancestral_tags(self.current_node),
            )
            if dia.ShowModal() == wx.ID_OK:
                if dia.output_options.GetSelection() == 0:
                    file_dlg = wx.FileDialog(
                        None,
                        message="Exporting Data URL...",
                        defaultDir=os.getcwd(),
                        defaultFile="data urls",
                        wildcard=".csv",
                        style=wx.SAVE | wx.FD_OVERWRITE_PROMPT,
                    )
                    if file_dlg.ShowModal() == wx.ID_OK:
                        os.chdir(os.path.split(file_dlg.GetPath())[0])
                        try:
                            myfile = open(file_dlg.GetPath(), "wb")
                            wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
                            for row in dia.get_selected_urls():
                                wr.writerow(row)
                            myfile.close()
                            file_dlg.Destroy()
                        except:
                            err_dlg = wx.MessageDialog(
                                None, "Cant open file for writing", "Error", wx.OK | wx.ICON_ERROR
                            )
                            err_dlg.ShowModal()

                if dia.output_options.GetSelection() == 1:
                    file_dlg = wx.FileDialog(
                        None,
                        message="Exporting Data URL...",
                        defaultDir=os.getcwd(),
                        defaultFile="data urls",
                        wildcard=".csv",
                        style=wx.SAVE | wx.FD_OVERWRITE_PROMPT,
                    )
                    if file_dlg.ShowModal() == wx.ID_OK:
                        os.chdir(os.path.split(file_dlg.GetPath())[0])
                        myfile = open(file_dlg.GetPath(), "wb")
                        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
                        for row in dia.get_all_urls():
                            wr.writerow(filter(None, row))
                        myfile.close()
                        file_dlg.Destroy()

                if dia.output_options.GetSelection() == 2:
                    image_urls = []
                    for row in dia.get_selected_urls():
                        image_urls.append(row[3])

                    if os.path.isfile("C:\Program Files\ImageJ\ImageJ.exe") is False:
                        for r, d, f in os.walk("c:\\"):
                            if r.endswith("ImageJ"):
                                for files in f:
                                    if files == "ImageJ.exe":
                                        ImageJPath = os.path.join(r, files)
                        if not ImageJPath:
                            err_dlg = wx.MessageDialog(
                                None,
                                "ImageJ was not found in C\Program Files directory to show images!!",
                                "Error",
                                wx.OK | wx.ICON_ERROR,
                            )
                            err_dlg.ShowModal()
                            return
                    else:
                        # TO DO: check the image format and image path are compatible with mageJ
                        ImageJPath = "C:\Program Files\ImageJ\ImageJ.exe"

                    subprocess.Popen("%s %s" % (ImageJPath, " ".join('"' + item + '"' for item in image_urls)))
            dia.Destroy()