Thursday, September 22, 2011

Let's try rotation

I am not too satisfied of the result. The interaction is not too convenient (key board+mouse), but for a first trial, that does the job. To rotate the chromosome, hit the r key of the keyboard to toggle between the drag-and-drop and the rotation modes.

Here is the script:

# -*- coding: utf-8 -*-
"""
Created on Mon Sep  5 15:44:42 2011

@author: jean-pat
"""
#!/usr/bin/env python
#
import os, pygame
import ConfigParser as CfgP
from pygame.locals import*

#def makeCfgFile():
#    config = CfgP.RawConfigParser()
#    config.add_section('shape classifier')
#    config.set('shape classifier', 'ref', '')
#    config.set('shape classifier', 'shape type', '')
#    return config
    
#def saveCfgFile(cfgfile,IKromList):
#    #building a config file
#    for s in IKromList:
#        print "saving config"
#        cref=s.ref
#        ctype=s.type
#        config.add_section(cref)
#        config.set(cref,'shape type', ctype)
#    config.write(open('shape.cfg','w'))
#    print "config saved"                
def readconfiguration():
    """
    read path to particles to classify:
        [Fluorochrome]
            Counter stain='DAPI'
            Probes=('Cy3','Cy5,'FITC')
        [Images Path]    
            work dir=...
            user=...
            slide=...
            field list=...
        [Classifier]
            screen size=(1024,768)
            category number=4
            category list=(single chromosome,touching chromosomes,nuclei,dust)
            box size=(200,100)
            first box=(5,650)
            box hspacing=30
 """
def load_image(name, colorkey=None):
    fullname=os.path.join("data", name)
    try:
        image=pygame.image.load(fullname)
    except pygame.error, message:
        print "Impossible de charger l'image:",name
        raise SystemExit, message
    image = image.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()
    
                
class Ichrom(pygame.sprite.Sprite):
    def __init__(self,image,ref,initpos):
        pygame.sprite.Sprite.__init__(self)
        self.ref=ref#particule name
        self.type=""
        self.pos = initpos
        self.image,self.rect=image
        self.original=image
        self.rotation=0
        self.mode="translation"
        #print "self.rect",self.rect,"-self.image:",self.image
        self.button=(0,0,0)#mouse buttons not pressed
        #self.selected = 0
        self.mouseover=False
        self.focused=False
        self.rect.topleft=initpos
        print "init chrom at ",self.pos
    def rollover(self,rotationmode):
        """Test if the mouse fly over the chromosome 
        self.mouseover==True if mouse flying over the chrom,
        False if not"""
        mpos=pygame.mouse.get_pos()#mouseposition
        #test if mouse roll over the sprite
        if rotationmode==0:
            self.mode="translation"
        if rotationmode==1:
            self.mode="rotation"
            print pygame.mouse.get_rel()
        if self.rect.collidepoint(mpos):
            self.mouseover=True
        else:
            self.mouseover=False
            
    def update(self,classifiergroup,background):
        self.button=pygame.mouse.get_pressed()
        mpos = pygame.mouse.get_pos()
        self.selected=self.rect.collidepoint(mpos)
        #the mouse flies over a chromosome
        if (self.mouseover):
            if self.mode=="translation":
                #print "mouse pos:",mpos
                collision=pygame.sprite.spritecollide(self,classifiergroup,False)
                #collision should contains only one element            
                if len(collision)>0:
                    #print collision[0].category
                    self.type=collision[0].category
                    print "particle "+self.ref+" is classified to "+self.type
                if self.button==(1,0,0):     
                    pos = pygame.mouse.get_pos()
                    self.rect.center = pos
            elif self.mode=="rotation":
                #test mouse movement
                mrel=pygame.mouse.get_rel()
                if self.rotation>=360:
                    self.rotation=0
                    self.image=self.original
                elif mrel[0]>0:
                    self.rotation=self.rotation+10
                    self.image=pygame.transform.rotate(self.original[0],self.rotation)
                    self.rect=self.image.get_rect(center=self.rect.center)
                elif mrel[0]<0:
                    self.rotation=self.rotation-10
                    self.image=pygame.transform.rotate(self.original[0],self.rotation)
                    self.rect=self.image.get_rect(center=self.rect.center)
                
class Classifier(pygame.sprite.Sprite):
    '''When a chrom is moved is moved into a category '''
    def __init__(self,initpos,category):
        pygame.sprite.Sprite.__init__(self)
        self.category=category
        self.image = pygame.Surface((100,100))
        self.image.set_colorkey((0,0,0))
        self.image = self.image.convert_alpha()
        self.rect= self.image.get_rect()
        #pygame.draw.rect(screen, color, (x,y,width,height), thickness)
        pygame.draw.rect(self.image, (255,0,0,255), (0,0,100,100),1)
        self.rect.topleft= initpos
        
    def update(self): 
        pass        
        
def main():
    pygame.init()
    screen = pygame.display.set_mode((320,300))
    pygame.display.set_caption("Karyotyper")
    pygame.mouse.set_visible(True)
    
    background = pygame.Surface(screen.get_size())
    background = background.convert()
    background.fill((0, 0, 0))

    screen.blit(background,(0, 0))
    pygame.display.flip()
    
    i1=load_image("/home/claire/Applications/ImagesTest/jp/Jpp48/13/DAPI/particules/part15.png", -1)
    i2=load_image("/home/claire/Applications/ImagesTest/jp/Jpp48/13/DAPI/particules/part12.png", -1)
    chr1 = Ichrom(i1,"part15",(0,0))
    #chr1 = Krom(i1,(0,0))
    chr2=Ichrom(i2,"part12",(30,30))
    #chr2=Krom(i2,(30,30))
    categ1=Classifier((5,150),"single")
    categ2=Classifier((110,150),"overlapping")
    categ3=Classifier((215,150),"other stuff")
    
    allsprites = pygame.sprite.RenderPlain((chr1,chr2))
    allcategories=pygame.sprite.RenderPlain((categ1,categ2,categ3))
    clock = pygame.time.Clock()
    
    config = CfgP.RawConfigParser()
    spritelist=(chr1,chr2)
    rotationmode=0
    while 1:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                #spritelist=(chr1,chr2)
                #building a config file
                #saveCfgFile(config,spritelist)
                for s in spritelist:
                    print "saving config"
                    cref=s.ref
                    ctype=s.type
                    config.add_section(cref)
                    config.set(cref,'shape type', ctype) 
                config.write(open('shape.cfg','w'))
                print "config saved"                
                return
            elif event.type == KEYDOWN and event.key == K_r:
                rotationmode=rotationmode+1
                if rotationmode==1:
                    print "rotation ON"
                if rotationmode==2:
                    print "rotation OFF"
                    rotationmode=0
            if event.type ==pygame.MOUSEBUTTONDOWN:
                #need to be modified to handle a list of chromosomes
                chr1.rollover(rotationmode)
                chr2.rollover(rotationmode)
                
        allsprites.update(allcategories,background)
        allcategories.update()
        ##
        ##Search which chromosome is moved
        ##into which category and classify  
        ##that chromosome in that category
#        collision=pygame.sprite.groupcollide(allcategories,allsprites,False,False,None)
#        for classified in collision.keys():
#            print classified
        screen.blit(background,(0,0))
        allsprites.draw(screen)
        allcategories.draw(screen)
        pygame.display.flip()
    
if __name__ == '__main__': main()

No comments: