Package bgu.bio.algorithms.alignment

Source Code of bgu.bio.algorithms.alignment.Check2$Job

package bgu.bio.algorithms.alignment;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.Queue;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;


import bgu.bio.adt.queue.BlockingQueue;
import bgu.bio.util.IdentityScoringMatrix;
import bgu.bio.util.ScoringMatrix;
import bgu.bio.util.alphabet.AlphabetUtils;
import bgu.bio.util.alphabet.RnaAlphabet;

public class Check2 {

  private char[] str1, str2;
 
  private int length1, length2;
 
  private double[] lineA, lineB, lineC;
 
  private ScoringMatrix scoringMatrix;
 
  private AlphabetUtils alphabet;
 
  //private bgu.bio.adt.queue.BlockingQueue<Job> jobs;
 
  private Queue<Job> jobs;
 
  private int cells;
 
  private AtomicInteger jobsCounter; //???
 
  private Object lock = new Object();
  private Object consumers = new Object();
 
  private boolean running = true;
 
  private int numOfWorkers;
 
  private Worker[] workers;
 
  private Job[] jobsPool;
 
//  private double time1,/* time4, time3,*/ time5;
 
  private boolean mainFinished = false;
 
 
  public Check2(String s1,String s2,AlphabetUtils alphabet, ScoringMatrix matrix, int numWorkers, int jobSize){
    this.scoringMatrix = matrix;
    this.alphabet = alphabet;
   
    int size1 = s1.length();
    int size2 = s2.length();
   
    if(size1 <= size2){ //s1 is shorter
      length1 = size1;
      length2 = size2;
      this.str1 = s1.toCharArray();
      this.str2 = s2.toCharArray();
    }
    else{ //s2 is shorter
      length1 = size2;
      length2 = size1;
      this.str1 = s2.toCharArray();
      this.str2 = s1.toCharArray();
    }
    //initializing the lines which need to be filled
    //the two diagonals should be in the length of the shorter string + 1:
    lineA = new double[length1+1];
    lineB = new double[length1+1];
    lineC = new double[length1+1];
   
    numOfWorkers = numWorkers;
    cells = jobSize;
   
    //creating the working objects which will fill in the table
    workers = new Worker[numOfWorkers];
    for(int i=0; i<numOfWorkers; i++){
      workers[i] = new Worker(i);
    }
   
    int capacity = (length1/cells)+1;
  //  System.out.println(capacity);
    jobs = new LinkedList<Job>(); //the maximal amount of jobs is the longest diagonal divided by the required cells
   
    jobsPool = new Job[capacity];
    for(int i=0; i<capacity; i++){
      jobsPool[i] = new Job();
    }
    jobsCounter = new AtomicInteger(0);
  }
 
 
 
  private void buildMatrix(){
    for(int i=0; i<length1+1; i++){
      lineA[i] = Math.ceil(Math.random()*100);
      lineB[i] = Math.ceil(Math.random()*100);
    }
   
    for(int k=0; k<numOfWorkers; k++){
      workers[k].start();
    }
   
    System.out.println(new Date());
    for(int i=0; i<30000; i++){
      concurrent(length1+4, 4, length1+1, 'c');
    /*  if(i%500 == 0)
        System.out.println("time spent so far on 'concurrent' 1st part: " + time1);*/
    //  System.out.println(i);
    }
    System.out.println(new Date());
   
  //  System.out.println("total time spent on concurrent (without waiting) " + time1);
//    System.out.println("total time spent on concurrent - first assigning " + time3);
//    System.out.println("total time spent on concurrent - second assigning " + time4);
  //  System.out.println("total time spent on concurrent - pushing to queue " + time5);

  //  System.out.println("total time spent on helpfill " + time4);
   
    running = false;
   
    double work = 0, wait = 0;
    Job j = new Job();
    j.numOfCells = -1;
       
    for(int m=0; m<numOfWorkers; m++){
    //  System.out.println("thread " + m + " waiting time = " + workers[m].time2 + " working time = " +  workers[m].time3);
    //  work += workers[m].time3;
    //  wait += workers[m].time2;
      //workers[m].interrupt();
      jobs.add(j);
    }
   
    synchronized (consumers) {
      //System.out.println("releasing threads");
      //mainFinished = true;
      for(int t=0; t<numOfWorkers; t++)
        workers[t].shouldWork = true;
      consumers.notifyAll();
    }
   
    System.out.println("waiting average: " + wait/24 + " working average: " + work/24);
    /*
    for(int i=0; i<length1+1; i++){
      System.out.println(lineC[i] + " ");
    }*/
  }
 
 
  private void concurrent(int sum, int j, int numOfCellsInDiagonal, char c){
  //  mainFinished = false;
    //long startTime1 = System.currentTimeMillis();
    jobsCounter.set(0);
    int i = 1;
    int columnIndex = j;
    int res = numOfCellsInDiagonal/cells;
    int iterations = numOfCellsInDiagonal%cells==0 ? res : res+1;   
  //  System.out.println("main dividing a new diagonal to jobs of 100 cells");
//    synchronized(lock2){
    long /*startTime3, startTime4, endTime3, endTime4,*/ startTime5, endTime5;
    Job job;
    while(i<=iterations){
      //startTime3 = System.currentTimeMillis();
      job = jobsPool[i-1];
      job.beginningColumn = columnIndex;
      job.beginningRow = sum - columnIndex;
      //endTime3 = System.currentTimeMillis();
      //time3 += (double)(endTime3 - startTime3)/60000;
     
    //  startTime4 = System.currentTimeMillis();
      job.howMany = iterations;
      job.c = c;
      if(i==iterations) //the last iteration - the last job will be the remaining amount of cells  
        job.numOfCells = numOfCellsInDiagonal - (iterations -1)*cells;
      else //in all iterations except the last one, the job will be the regular number of cells to fill
        job.numOfCells = cells;
    //  endTime4 = System.currentTimeMillis();
    //  time4 += (double)(endTime3 - startTime3)/60000;
     
    //  startTime5 = System.currentTimeMillis();
      //synchronized (consumers) {
        jobs.add(job);
      //}
    //  endTime5 = System.currentTimeMillis();
    //  time5 += (double)(endTime5 - startTime5)/60000;
     
      columnIndex += cells;
      i++;
    }
    //System.out.println("main going to release threads");
    synchronized (consumers) {
      //System.out.println("releasing threads");
      //mainFinished = true;
      for(int t=0; t<numOfWorkers; t++)
        workers[t].shouldWork = true;
      consumers.notifyAll();
    }
   
  //  long endTime1 = System.currentTimeMillis();
   
  //  time1 += (double)(endTime1 - startTime1)/60000;
   
   
   
    synchronized(lock){
      while(jobsCounter.get()!=numOfWorkers){
        try {
          lock.wait();
        } catch (InterruptedException e) {
          System.out.println("this message should never be printed since no one interrupts main");
        }
      }
    }
    System.out.println("blabla");
  }
 
 
 
 
  private final double similarity(int i, int j) {
    final char c1 = i==0 ? alphabet.emptyLetter() : str1[i - 1]; //if i=0 than no letter was read from str1
    final char c2 = j==0 ? alphabet.emptyLetter() : str2[j - 1]; //if j=0 than no letter was read from str2
    return scoringMatrix.score(c1,c2);
  }
 
 
  public int getLength(int i){
    if(i==1)
      return length1;
    else
      return length2;
  }
 
 
  /**
   * Main..............................................................................................
   * @param args
   */
  public static void main (String[] args){
    FileReader input1=null, input2=null;
   
    //reading s1 from a file
    StringBuffer s1 = new StringBuffer();
   
    try {
      input1 = new FileReader(args[0]); //get the argument
    } catch (FileNotFoundException e) {
      System.out.println("where is file 1?");
      e.printStackTrace();
    }
    BufferedReader buf1 = new BufferedReader(input1);
    String lineFromF1;

    try {
      lineFromF1 = buf1.readLine();
      while(lineFromF1!=null){
        s1.append(lineFromF1); //connects the string to the StringBuffer
        lineFromF1 = buf1.readLine();
      }
      buf1.close(); //close the buffered reader
     
    } catch (IOException e1) {
      System.out.println("IO problem in F1");
      e1.printStackTrace();
    }
    String str1 = s1.toString(); //cast the StringBuffer to string, so we could handle it in the DiagoalSequenceAlignment class
   
    //same process for s2...
    StringBuffer s2 = new StringBuffer();
    try {
      input2 = new FileReader(args[1]);
    } catch (FileNotFoundException e) {
      System.out.println("where is file 2?");
      e.printStackTrace();
    }

    BufferedReader buf2 = new BufferedReader(input2);
    String lineFromF2;

    try {
      lineFromF2 = buf2.readLine();
      while(lineFromF2!=null){
        s2.append(lineFromF2); //connects the string to the StringBuffer
        lineFromF2 = buf2.readLine();
      }
      buf2.close(); //close the buffered reader
     
    } catch (IOException e1) {
      System.out.println("IO problem in F2");
      e1.printStackTrace();
    }
    String str2 = s2.toString(); //cast the StringBuffer to string, so we could handle it in the DiagoalSequenceAlignment class
   
    int n = Integer.parseInt(args[2]); //number of workers
   
    int jobSize = Integer.parseInt(args[3]); //amount of cells for each thread to fill
   
   
    Check2 alignment = new Check2(str1, str2, RnaAlphabet.getInstance(),
        new IdentityScoringMatrix(RnaAlphabet.getInstance()), n, jobSize);
   
   
    System.out.println("shorter string length: " + alignment.getLength(1));
    System.out.println("longer string length: " + alignment.getLength(2));
    System.out.println("amount of diagonals = " + (alignment.getLength(1)+alignment.getLength(2)));
   
    alignment.buildMatrix();
 

   
    //System.out.println(alignment.getAlignmentScore());
    //alignment.printAlignments();
  //  alignment.printDPMatrix();
  //  alignment.printDPMatrixInLatexMatrix();
  //  System.out.println("The score of the alignment: " + alignment.getMaxScore());
  }
 
 
 
 
  private class Worker extends Thread{
   
    /**
     * The state
     */
    private volatile char c;
   
    /**
     * The Worker's ID number (for debug)
     */
    private int id; 
   
    /**
     * Flag which changes to 'true' only when a worker is given work to do, and changes back to 'false' when
     * the Worker is done working
     */
    volatile boolean shouldWork = false;
   
  //  private double time2, time3;

   
    /**
     * Constructor
     * @param id the unique ID number of the worker
     */
    public Worker(int id){
      this.id = id;
    }
   

 
   
    /**
     * The Worker run function which actually computes and writes the suiting values in dpTable and prevCells
     */
    @Override
    public void run() {
      while(running){ //the condition fails only when all of dpTable was filled

        synchronized(consumers) {
          try {
            while (!shouldWork) {
              consumers.wait();
            }
            shouldWork = false;
          } catch (InterruptedException e){
            return;
          }
        }
        //System.out.println("Size of queue= " + jobs.size());
        Job myJob = null;
       
       
        do {
        //  long startTime2 = System.currentTimeMillis();
          synchronized (jobs) {
            myJob = jobs.poll();
          }
          if (myJob != null) {
            if(myJob.numOfCells==-1)
              return;
        //    long endTime2 = System.currentTimeMillis();
      //      time2 += (double)(endTime2 - startTime2)/60000;
      //      synchronized(lock2){
            // fill the table
            int rowB = myJob.beginningRow; //row index of the first cell to be filled in the worker's job
            int colB = myJob.beginningColumn; //column index of the first cell to be filled in the worker's job
            int count = myJob.numOfCells; //counter for the number of unfilled cells
            char c = myJob.c;
            int k=0;
          //  System.out.println("worker commiting job: from [" + rowB + "][" + (colB) + "], filling up " + count + " cells, on diagonal of sum " + (rowB+colB));
            while(k < count){
              //actually filling the table
              if((colB+rowB < str1.length)){ //the first thread on the matrix, and the diagonal is on part 1
                helpFill(colB+k, colB+k, colB+rowB, c);
              }
              else{
                helpFill(str1.length-rowB+k, colB+k, colB+rowB, c);
              }
              k++;
            }

          //  }
          //  long endJob = System.currentTimeMillis();
          //  time3 += (double)(endJob - endTime2)/60000;
           

          }
        } while (myJob != null);

        int num = jobsCounter.incrementAndGet(); //indicates a job was done
        if(num == numOfWorkers){
          synchronized(lock){
            lock.notify();
          }
        }       
       
       
       
        /*
        try {
          long startTime2 = System.currentTimeMillis();
          synchronized (consumers) {
            myJob = jobs.poll();
            while(myJob == null){
          //    System.out.println("waiting");
              consumers.wait();
              myJob = jobs.poll();
            }
          }
        //  while(myJob == null)
      //      myJob = jobs.take(); //get a new job
          if(myJob.numOfCells==-1)
            return;
          long endTime2 = System.currentTimeMillis();
          time2 += (double)(endTime2 - startTime2)/60000;
    //      synchronized(lock2){
          // fill the table
          int rowB = myJob.beginningRow; //row index of the first cell to be filled in the worker's job
          int colB = myJob.beginningColumn; //column index of the first cell to be filled in the worker's job
          int count = myJob.numOfCells; //counter for the number of unfilled cells
          char c = myJob.c;
          int k=0;
        //  System.out.println("worker commiting job: from [" + rowB + "][" + (colB) + "], filling up " + count + " cells, on diagonal of sum " + (rowB+colB));
          while(k < count){
            //actually filling the table
            if((colB+rowB < str1.length)){ //the first thread on the matrix, and the diagonal is on part 1
              helpFill(colB+k, colB+k, colB+rowB, c);
            }
            else{
              helpFill(str1.length-rowB+k, colB+k, colB+rowB, c);
            }
            k++;
          }

        //  }
          long endJob = System.currentTimeMillis();
          time3 += (double)(endJob - endTime2)/60000;
          int num = jobsCounter.incrementAndGet(); //indicates a job was done
          if(num == myJob.howMany){
            synchronized(lock){
              lock.notify();
            }
          }
        } catch (InterruptedException e1) {
          return;
        }

*/
      }   
    }
   
 
    /**
     * Fill in one cell of the C diagonal according to the given indexes
     * @param indexLineC - location on diagonal C - the cell which needs to be filled
     * @param j - the current index in str2
     * @param sum the sum of j (index on str2) and the index on str1 (would have been i+j on a table)
     * @param c the state of computation (a, b or c) according to which we will fill lineC
     */
    private void helpFill(int indexLineC, int j, int sum, char c){
      //long startTime4 = System.currentTimeMillis();
     
      double diagScore = Double.NEGATIVE_INFINITY; //match or substitution
      double leftScore = Double.NEGATIVE_INFINITY; //a letter was read from str2
      double upScore = Double.NEGATIVE_INFINITY;  //a letter was read from str1
     
      /* special case used for the first time the diagonals are filled
       * lineA is actually the second diagonal (2 cells), lineB is the third diagonal (3 cells)
       * and they are filled according to the [0,0] cell (where necessary)
       */
     
      if(sum==1){
          lineA[0] = 0.0 + similarity(1,0); //up
          lineA[1] = 0.0 + similarity(0,1); //left
          return;
      }
      else if(sum==2){
        diagScore = 0.0 + similarity(1,1);
        upScore = lineA[1] + similarity(1,0);
        leftScore = lineA[0] + similarity(0,1);
        lineB[0] = lineA[0] + similarity(2,0); //up
        lineB[1] = max(diagScore, max(upScore, leftScore));
        lineB[2] = lineA[1] + similarity(0,2); //left
        return;
      }
     
      //the rest of the cases (sum>=3), beginning with edge cases:
     
      if(j==0){ //the first column - score can only be computed according to upScore
        if(c == 'a'){
          upScore = lineB[indexLineC] + similarity(sum-j, 0);
        }
        else if(c == 'b'){
          upScore = lineB[indexLineC+1] + similarity(sum-j, 0);
        }
      }
      else if(indexLineC == sum || indexLineC>=str1.length){ //the first row - score can only be computed according to leftScore
        if(c == 'a'){
          leftScore = lineB[indexLineC-1] + similarity(0, j);
        }
        else if(c == 'b'|| c == 'c'){
          leftScore = lineB[indexLineC] + similarity(0, j);
        }
      }
      else{ //j!=0 && indexLineC isn't on the first row => no problems, score is computed from all 3 directions
        if(c == 'a'){
          diagScore = lineA[indexLineC-1] + similarity(sum-j, j);
          upScore = lineB[indexLineC] + similarity(sum-j, 0);
          leftScore = lineB[indexLineC-1] + similarity(0, j);
        }
        else if(c == 'b'){
          diagScore = lineA[indexLineC] + similarity(sum-j, j);
          upScore = lineB[indexLineC+1] + similarity(sum-j, 0);
          leftScore = lineB[indexLineC] + similarity(0, j);
        }
        else{ //c == 'c'
          diagScore = lineA[indexLineC+1] + similarity(sum-j, j);
          upScore = lineB[indexLineC+1] + similarity(sum-j, 0);
          leftScore = lineB[indexLineC] + similarity(0, j);
        }
      }
      lineC[indexLineC] = max(diagScore, max(upScore, leftScore)); //determines which option will give the highest score
     
      //long endTime4 = System.currentTimeMillis();
      //time4 += (endTime4 - startTime4)/60000;
     
    //  System.out.println("indexlineC = " + indexLineC);
    //  lineC[indexLineC] = lineB[indexLineC];
    }
   
    /**
     * Returns the higher value: a or b
     */
    private final double max(double a,double b){
      return a > b ? a : b;
    }
 
   
    private final double similarity(int i, int j) {
      final char c1 = i==0 ? alphabet.emptyLetter() : str1[i - 1]; //if i=0 than no letter was read from str1
      final char c2 = j==0 ? alphabet.emptyLetter() : str2[j - 1]; //if j=0 than no letter was read from str2
      return scoringMatrix.score(c1,c2);
    }
   
   
  } //end of class Worker
 
 
  /**
   * Class Job
   */
  private class Job{
    private volatile int beginningRow; //the row index of the first cell in this job
    private volatile int beginningColumn; //the column index of the first cell in this job
    private volatile int numOfCells; //the amount of cells needs to be filled in this job
    private volatile int howMany; //this job is one of how many jobs?
    private volatile char c; //state of filling
  } //end of class Job
 
 
 
 
}
TOP

Related Classes of bgu.bio.algorithms.alignment.Check2$Job

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.