CSC334 DNA Align2 pde

From dftwiki3
Revision as of 20:03, 23 July 2008 by Thiebaut (talk | contribs) (New page: Back to Lab 3 <hr> <code> <pre> // DNA_Align.pde // D. Thiebaut // A Processing program for displaying exact matches of // FASTA-formatted DNA sequences //...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Back to Lab 3


// DNA_Align.pde
// D. Thiebaut
// A Processing program for displaying exact matches of 
// FASTA-formatted DNA sequences

//---------------------------------------------------------------------
//  ___ _     _          _    
// / __| |___| |__  __ _| |___
//| (_ | / _ \ '_ \/ _` | (_-<
// \___|_\___/_.__/\__,_|_/__/
//
//---------------------------------------------------------------------
DNAString dna1, dna2;
statusClass status;

String FASTA0 = "gi|194306025|dbj|AB426820.1| Escherichia coli ompT mRNA for outer membrane protease T, partial cds, strain: JCM 5491\n"
+"TGGGAATAGTCCTGACAACCCCTATTGCGATCAGCTCTTTTGCTTCTACCGAGACTTTATCGTTTACTCC"
+"TGACAACATAAATGCGGACATTAGTCTTGGAACTCTGAGCGGAAAAACAAAAGAGCGTGTTTATCTAGCC"
+"GAAGAAGGAGGCCGAAAGGTCAGTCAACTTGACTGGAAATTCAATAACGCTGCAATTATTAAAGGTGCAA"
+"TTAATTGGGATTTGATGCCCCAGATATCTATCGGGGCTGCTGGCTGGACAACTCTCGGTAGCCGAGGTGG"  
+"CAATATGGTCGATCGGGACTGGATGGATTCCAGTAACCCCGGAACCTGGACGGATGAAAGTAGACACCCT"
+"GATACACAACTCAATTATGCCAACGAATTTGATCTGAATATCAGAGGCTGGCTCCCCAACGAACCCAATT"
+"ACCGCCTGGGACTCATGGCCGGATATCAGGAAAGCCGTTATAGCTTTACAGCCAGAGGGGGTTCCTATAT"
+"CTACAGTTCTGAGGAGGGATTCAGAGATGATATCGGCTCCTTCCCGAATGGAGAAAGAGCAATCGGCTAC"
+"AAACAACGTTTTAAAATGCCCTACATTGGCTTGACTGGAAGTTATCGTTATGAAGATTTTGAGCTAGGTG"
+"GTACATTTAAATACAGCGGCTGGGTGGAAGCATTTGATAACGATGAACACTATGACCCAGGAAAAAGAAT"
+"CACTTATCGCAGTAAAGTCAAAGACCAAAATTACTATTCTGTTGCAGTCAATGCAGGTTATTACGTAACG"
+"CCTAATGCAAAAGTTTATATTGAAGGCGCATGGAATCGGGTTACGAATAAAAAAGGTGATACTTCACTTT"
+"ATGATCACAATGATAACACTTCTGACTACAGCAAAAATGGTGCAGGCATAGAAAACTATAACTTCATCAC"
+"TACTGCTGGTC";

String FASTA1 = "gi|194306025|dbj|AB426820.1| Escherichia coli ompT mRNA for outer membrane protease T, partial cds, strain: JCM 5491\n"
+"TGGGAATAGTCCTGACAACCCCTATTGCGATCAGCTCTTTTGCTTCTACCGAGACTTTATCGTTTACTCC";

String FASTA2 = "gi|194306025|dbj|AB426820.1| Escherichia coli ompT mRNA for outer membrane protease T, partial cds, strain: JCM 5491\n"
+"TGACAACATAAATGCGGACATTAGTCTTGGAACTCTGAGCGGAAAAACAAAAGAGCGTGTTTATCTAGCC";

//---------------------------------------------------------------------
// GEOMETRY
//---------------------------------------------------------------------
int WIDTH        = 1000;
int MIDWIDTH     = WIDTH/2;
int HEIGHT       = 400;
int BORDER       = 20;
int TITLELINE    = 50;
int ALINE        = 100;
int BLINE        = 130;
int MLINE        = 160;
int STATUSTOP    = 190;
int STATUSWIDTH  = (WIDTH-2*BORDER)/2;
int STATUSHEIGHT = HEIGHT-BORDER-STATUSTOP;
int LEGLENGTH    = (BLINE-ALINE)/2;  // length of leg below symbol
String MATCH     = "Match:";

PFont font;                          // the font used to display the symbols


//---------------------------------------------------------------------
// ___  _  _   _   ___            _         _ 
//|   \| \| | /_\ / __|_  _ _ __ | |__  ___| |
//| |) | .` |/ _ \\__ \ || | '  \| '_ \/ _ \ |
//|___/|_|\_/_/ \_\___/\_, |_|_|_|_.__/\___/_|
//                     |__/                   
// DNA Symbol Class
//---------------------------------------------------------------------
class DNASymbol {
    char symbol;    // the symbol
    color symColor; // color of symbol
    int currX;      // current X coordinates
    int currY;      // current Y coordinates
    
    DNASymbol() {  
        setSymbol( 'X' );
    }
    
    DNASymbol( char x ) {
        setSymbol( x );  
    }
    
    char getSymbol( ) {
        return symbol;
    }
    
    //--- set a symbol to a char representation and selects its color ---
    void setSymbol( char x ) {
        symbol = x;
        if ( x=='C' ) symColor = color( 249, 16, 85 );
        else if ( x=='G' ) symColor = color( 148, 73, 232 );
        else if ( x=='T' ) symColor = color( 122, 186, 221 );
        else if ( x=='A' ) symColor = color( 169, 209, 169 );
        else symColor = color( 200, 200, 200 );
    }
    
    //--- draws the symbol at location x,y ---
    void draw( int x, int y ) {
        currX = x;
        currY = y;
        fill( symColor );
        text( str( symbol ), x, y );
    }
    
    
    //--- drawBarDown: draws a line below the symbol ---
    void drawBarDown() {
        fill( 255 );
        stroke( 255 );
        line( currX+textWidth( symbol )/2, currY+2, currX+textWidth( symbol )/2, currY+LEGLENGTH );
    }    
}

//---------------------------------------------------------------------
// ___  _  _   _   ___ _       _           
//|   \| \| | /_\ / __| |_ _ _(_)_ _  __ _ 
//| |) | .` |/ _ \\__ \  _| '_| | ' \/ _` |
//|___/|_|\_/_/ \_\___/\__|_| |_|_||_\__, |
//                                   |___/ 
// DNAString Class: a class holding a DNA sequence, both as a text string
// and as an array of DNASymbol objects.
//---------------------------------------------------------------------
class DNAString {
    String symbols;     // the string of chars
    int noSymbols;      // the # of symbols
    DNASymbol[] array;  // the array of symbol objects (char, color)
    boolean[] legs;     // indicate if each symbol has a leg or not
    int offsetX;        // x-value of left-most position on screen
    int offsetY;        // y-value of screen position
    int leftPadding;    // amount of left padding when sequence shifts
                        // this is relative to leftmost position, in integer
                        // number of symbols
    int maxLeftPadding;
    
    //--- default constructor ---
    DNAString( ) {      
        symbols = "";
        noSymbols = 0;
        offsetX = int( 2*BORDER+textWidth( MATCH ));
        offsetY = ALINE;
        leftPadding = 0;
    }
    
    //--- constructor ---
    DNAString( String fastaString ) {
        String[] list = split( fastaString, '\n' );
        symbols = list[1];
        noSymbols = symbols.length();
        array = new DNASymbol[ noSymbols ];
        legs  = new boolean[ noSymbols ];
        
        for ( int i=0; i< noSymbols; i++ ) {
            array[i] = new DNASymbol( symbols.charAt(i) );
            legs[i] = false;
        }
        offsetX = int( 2*BORDER+textWidth( MATCH ));
        offsetY = ALINE;
        leftPadding = (int) ( (WIDTH-BORDER-offsetX-textWidth( symbols ) ) / 2 / textWidth( "A" ) ) ;
    }    
    
    void setMaxPadding( int mmax ) {
        maxLeftPadding = mmax;
    }
    
    int getLeftPadding() {
        return leftPadding; 
    }
    
    void shiftLeft() {
        leftPadding = max(0, leftPadding-1);
    }
    
    void shiftRight() {
        leftPadding = min(leftPadding+1, maxLeftPadding );
    }
    
    void setOffsets( int x, int y ) {
        offsetX = x;
        offsetY = y;
    }
    
    //--- returns the string of symbols ---
    String getText() {  
        return symbols;
    }
    
    int length() {
        return noSymbols;
    }
    
    //--- display text using default method ---
    void drawText() {   
        float tw = textWidth( "A" );
        text( symbols, offsetX, offsetY );
    }
    
    
    //--- displays symbols as individual items ---
    void drawSymbols() {
        float tw = textWidth( "A" );
        for ( int i=0; i<noSymbols; i++ ) {
            array[i].draw( offsetX+int( (i+leftPadding) * tw ), offsetY );
            if ( legs[i] ) array[i].drawBarDown();
        }
    }
    
    //--- setLeg: add a leg to symbol at index i ---
    void setLeg( int i ) {
        legs[i] = true;
    }
    
    //--- erase the symbols and the legs, if any ---
    void erase() {
        int tw = int( textWidth( "A" ) );
        fill( 0 );
        stroke( 0 );
        rect( offsetX+leftPadding*tw, offsetY-12, noSymbols*tw, 12+LEGLENGTH );
        for ( int i=0; i<noSymbols; i++ ) 
            legs[i] = false;
    }
    
}

//---------------------------------------------------------------------
//    _        _            ___ _            
// __| |_ __ _| |_ _  _ ___/ __| |__ _ ______
//(_-<  _/ _` |  _| || (_-< (__| / _` (_-<_-<
///__/\__\__,_|\__|\_,_/__/\___|_\__,_/__/__/
//
//---------------------------------------------------------------------
class statusClass {
    String[] lines;
    int[] X;
    int[] Y;
    color myColor = color( 99, 66, 204 );
    
    statusClass() {
        lines = new String[5];  
        X = new int[5];
        Y = new int[5];
        for ( int i=0; i<5; i++ ) {
            lines[i] = str( i+1 ) + ".";
            X[i] =  BORDER + int( textWidth( "A" ) );
            Y[i] = STATUSTOP+22 + i * (STATUSHEIGHT / (5+1) );
        }
        draw();
    }
    
    void print( int i, String s ) {
        lines[i] = s;
        draw();
    }
    
    void draw() {
        //--- erase the rectangle first ---
        fill( 0 );
        stroke( myColor );
        rect( BORDER, STATUSTOP, STATUSWIDTH, STATUSHEIGHT );
        fill( myColor );
        fill( 0 );
        stroke( 0 );
        int tw = int( textWidth( "Status" ) );
        rect( BORDER+5, STATUSTOP, tw, 12 );
        fill( myColor );
        text( "Status", BORDER+5, STATUSTOP+4 );
        
        for ( int i=0; i<5; i++ )   
            text( lines[i], X[i], Y[i] );
    } 
}


//---------------------------------------------------------------------
// ___             _   _             
//| __|  _ _ _  __| |_(_)___ _ _  ___
//| _| || | ' \/ _|  _| / _ \ ' \(_-<
//|_| \_,_|_||_\__|\__|_\___/_||_/__/
//---------------------------------------------------------------------

//---------------------------------------------------------------------
// INITFONT: initialize the fonts (must be nonproportional ---
//---------------------------------------------------------------------
void initFont( ) {  
    font = loadFont( "Monaco-12.vlw" );
    textFont( font );
}

//---------------------------------------------------------------------
// INITWINDOW: Draw the fixed text in the window
//---------------------------------------------------------------------
void initWindow( String title ) {
    color myColor = color( 99, 66, 204 );
    fill( myColor );
    text( title, BORDER, TITLELINE );
    textSize( 12 );
    text( "A:", BORDER, ALINE );
    text( "B:", BORDER, BLINE );
    text( "Match:", BORDER, MLINE );  
    
    //--- setup Status box ---
    status = new statusClass();
    status.print( 0, "Status Box" );
    
}

//---------------------------------------------------------------------
// SETUP: <=== STARTUP POINT.  PROCESSING STARTS HERE!!!
//---------------------------------------------------------------------
void setup() {
    size( WIDTH, HEIGHT );
    initFont();
    background( 0 );
    noStroke();   

    //--- initialize the window ---
    initWindow( "DNA Alignment" );
    
    //--- create the first DNA string, and position it in window ---
    dna1 = new DNAString( FASTA1 );
    dna1.setOffsets( int( 2*BORDER+textWidth( MATCH )) , ALINE );
    
    //--- create 2nd DNA string and position it in window ---
    dna2 = new DNAString( FASTA2 );
    dna2.setOffsets( int( 2*BORDER+textWidth( MATCH )) , BLINE );
    
    //--- make each sequence know the length of the other, so that shifting
    //--- is limited. 
    dna1.setMaxPadding( dna2.length() );
    dna2.setMaxPadding( dna1.length() );

    //--- find exact matches between the 2 sequences  ---
    findMatching();

    //--- draw both sequences ---
    dna1.drawSymbols();
    dna2.drawSymbols();
    
}

//---------------------------------------------------------------------
// DRAW:  This is called many times a second.  Use it to do animation.
//---------------------------------------------------------------------
void draw() {
  
}

//---------------------------------------------------------------------
// FINDMATCHING: finds matching symbols between the two sequences in
//        their current alignment.
//---------------------------------------------------------------------
void findMatching() {

  int pad1 = dna1.getLeftPadding();
  int pad2 = dna2.getLeftPadding(); 
  int start1 = 0;                    // where we start comparing Sequence 1
  int start2 = 0;                    // where we start comparing Sequence 2
  int end1 = dna1.length()-1;        // where we end looking at Sequence 1
  int end2 = dna2.length()-1;        // where we end looking at Sequence 2
  String dnaChar1 = dna1.getText();  // String representation of Sequence 1
  String dnaChar2 = dna2.getText();  //  "          "         "     "     2
  
  //println( "pad1="+pad1+" start1="+start1+" end1="+end1);
  //println( "pad2="+pad2+" start2="+start2+" end2="+end2);

  //--- figure out which sequence extends past the other ---
  if ( pad1 > pad2 ) 
    start2 = pad1 - pad2;
  if ( pad2 > pad1 ) 
    start1 = pad2 - pad1; 
  if ( pad1+end1 > pad2+end2 )
    end1 = pad2+end2+1;
  if ( pad1+end1 < pad2+end2 )
    end2 = pad1+end1+1;
      
  //--- find the exact matches, and create a line between matching symbols ---
  int noMatches = 0;
  for ( int i=start1, j=start2; i<=end1 && j<=end2; i++, j++ ) 
     if ( dnaChar1.charAt( i )==dnaChar2.charAt( j ) ) {
         dna1.setLeg( i );
         noMatches += 1;
     }

  //--- display result in status box ---
  status.print( 0, "Number of maching symbols: " + str( noMatches ) );
  
}

//---------------------------------------------------------------------
// KEYPRESSED(): called every time a key is pressed.  if + or = are pressed
// shift dna strings one way, if - or _ are pressed, shift the other way.
//---------------------------------------------------------------------
boolean ping=true;  // do not shift both of them at once!

void  keyPressed() {
    //--- + or = are pressed... shift top one right, bottom one left ---
    if (key=='+' || key=='=' ) {
        dna1.erase();
        dna2.erase();
        if ( ping ) 
            dna1.shiftLeft();
        else 
            dna2.shiftRight();
        findMatching();
        dna1.drawSymbols();
        dna2.drawSymbols();
    }
     
    //--- - or _ have been pressed. Shift top one left, bottom one right---
    if (key=='-' || key=='_' ) {
        dna1.erase();
        dna2.erase();
        if ( ping )  
            dna2.shiftLeft();
        else
            dna1.shiftRight();
        findMatching();
        dna1.drawSymbols();
        dna2.drawSymbols();
    } 

    //--- make sure next time we alternate the shifting ---
    ping = !ping;
}

 


 



Back to Lab 3