package com.ppfold.algo; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; /** * Created by FoldingProject, steers asynchronous execution with queues * * @author Z.Sukosd * @author M.Vaerum * @see FoldingProject */ public class Master { Sector top; Sector bottom; double[][] prob; BlockingQueue<CYKJob> jobChannelInside = new LinkedBlockingQueue<CYKJob>(); BlockingQueue<CYKJob> jobChannelOutside = new LinkedBlockingQueue<CYKJob>(); BlockingQueue<CYKJob> jobChannelExpectation = new LinkedBlockingQueue<CYKJob>(); public Master() { } public Master(Sector topsec, double[][] prob) { top = topsec; bottom = findBottom(); this.prob = prob; } public boolean outsideFinished() { // returns true if outside is finished, otherwise false Sector current = bottom; while (current.pos[1] == -1 && current.next != null) { if (current.getOutsideResults() == null) { return false; } current = current.next; } return true; } public void CreateInsideJobChannel() { Sector sec = this.bottom; // loop to create inside jobchannel while (sec != null && sec.below == null) { // first job to have below != null is the first one outside the // zeroth row // ie. enough to check sec.below, loop exists at the right time try { jobChannelInside.put(createInsideJobFromSector(sec)); sec.setIsBeingInsideProcessed(true); } catch (InterruptedException e) { //System.out.println("Process interrupted!"); } sec = sec.next; } } public CYKJob takeNextInsideJob() throws InterruptedException { return jobChannelInside.take(); } public void CreateOutsideJobChannel() { // create outside jobchannel - consists of top job to start with try { jobChannelOutside.put(createOutsideJobFromSector(top)); } catch (InterruptedException e) { //System.out.println("Process interrupted!"); } } public CYKJob takeNextOutsideJob() throws InterruptedException { return jobChannelOutside.take(); } public void CreateExpectationJobChannel() { Sector sec = this.bottom; // loop to create expectation jobchannel while (sec != null && sec.below == null) { // first job to have below != null is the first one outside the // zeroth row // ie. enough to check sec.below, loop exists at the right time try { jobChannelExpectation.put(createExpectationJobFromSector(sec)); sec.setIsBeingExpectationProcessed(true); } catch (InterruptedException e) { //System.out.println("Process interrupted!"); } sec = sec.next; } } public CYKJob takeNextExpectationJob() throws InterruptedException { return jobChannelExpectation.take(); } public synchronized boolean unProcessedInsideSectors() { return !jobChannelInside.isEmpty() || (top.getInsideResults() == null && !top .isBeingInsideProcessed()); } public synchronized boolean unProcessedOutsideSectors() { // returns true if: // there are jobs in outside queue // there is at least one job with getOutsideResults()==null // there is at least one job with isBeingOutsideProcessed() = true boolean value = false; Sector current = bottom; while (current.pos[1] == -1 && current.next != null) { if (current.getOutsideResults() == null && !current.isBeingOutsideProcessed()) { value = true; } current = current.next; } return !jobChannelOutside.isEmpty() || value; } public synchronized boolean unProcessedExpectationSectors() { return !jobChannelExpectation.isEmpty() || (top.getExpectationResults() == null && !top .isBeingExpectationProcessed()); } public synchronized void setInsideResult(int sectorNumber, JobResults results) { // Traverse sector structure and find the sector Sector sector = findSector(sectorNumber); // Update sector with result sector.setInsideResults(results); sector.setIsBeingInsideProcessed(false); // Check to see if a new job is ready and insert into queue if (sector.above != null && sector.above.readyForInsideProcessing()) { processInside(sector.above); } if (sector.diagabove != null && sector.diagabove.readyForInsideProcessing()) { processInside(sector.diagabove); } } public synchronized void setOutsideResult(int sectorNumber, JobResults results) { // Traverse sector structure and find the sector Sector sector = findSector(sectorNumber); // Update sector with result sector.setOutsideResults(results); sector.setIsBeingOutsideProcessed(false); // Check to see if a new job is ready and insert into queue if (sector.below != null && sector.below.readyForOutsideProcessing()) { processOutside(sector.below); } if (sector.diagbelow != null && sector.diagbelow.readyForOutsideProcessing()) { processOutside(sector.diagbelow); } } public synchronized void setExpectationResult(int sectorNumber, JobResults results) { // Traverse sector structure and find the sector Sector sector = findSector(sectorNumber); // Update sector with result sector.setExpectationResults(results); sector.setIsBeingExpectationProcessed(false); // Check to see if a new job is ready and insert into queue if (sector.above != null && sector.above.readyForExpectationProcessing()) { processExpectation(sector.above); } if (sector.diagabove != null && sector.diagabove.readyForExpectationProcessing()) { processExpectation(sector.diagabove); } } private void processInside(Sector sector) { sector.setIsBeingInsideProcessed(true); CYKJob nextJob = createInsideJobFromSector(sector); // System.out.println("Job created from sector " + sector.sectorid); try { jobChannelInside.put(nextJob); } catch (InterruptedException e) { //System.out.println("Process interrupted!"); } } private void processOutside(Sector sector) { sector.setIsBeingOutsideProcessed(true); CYKJob nextJob = createOutsideJobFromSector(sector); // System.out.println("Job created from sector " + sector.sectorid); try { jobChannelOutside.put(nextJob); } catch (InterruptedException e) { //System.out.println("Process interrupted!"); } } private void processExpectation(Sector sector) { sector.setIsBeingExpectationProcessed(true); CYKJob nextJob = createExpectationJobFromSector(sector); // System.out.println("Job created from sector " + sector.sectorid); try { jobChannelExpectation.put(nextJob); } catch (InterruptedException e) { //System.out.println("Process interrupted!"); } } private CYKJob createInsideJobFromSector(Sector sector) { PointRes tmp = new PointRes(0, 0); CYKJob cYKJob = new CYKJob(sector.sectorid, sector.dim, 0); Sector current = sector; while (current.below != null) { current = current.below; cYKJob.addBelowL(current, false); } current = sector; while (current.diagbelow != null) { current = current.diagbelow; cYKJob.addDiagBelowS(current, false); } current = sector.below; if (current != null) { for (int i = 0; i < sector.dim; i++) { cYKJob.setInsideVertF(current, i, tmp); } } current = sector.diagbelow; if (current != null) { for (int i = 0; i < sector.dim; i++) { cYKJob.setInsideDiagF(current, i, tmp); } Sector other = current.below; if (other != null) { // cYKJob.specialF = // sector.diagbelow.below.getMatrixInsideFTpVal(sector.dim-1, // sector.dim-1).clone(); cYKJob.specialF.copyFrom(sector.diagbelow.below .getMatrixInsideFTpVal(sector.dim - 1, sector.dim - 1, tmp)); } } cYKJob.setData(sector.dim, sector.getMini(), sector.getMinj(), sector.seqlength, prob); cYKJob.basepairs = sector.getBasePairs(); if(sector.diffbp){ cYKJob.basepairs2 = sector.getBasePairs2(); cYKJob.setDiffBasepairs(true); } return cYKJob; } private CYKJob createOutsideJobFromSector(Sector sector) { PointRes tmp = new PointRes(0, 0); CYKJob cYKJob = new CYKJob(sector.sectorid, sector.dim, 1); Sector current = sector; cYKJob.setFullseqlength(sector.fullseqlength); // System.out.println("Pushing INSIDE of job nr. " + sector.sectorid + // " into insideresultsL, insideresultsS"); cYKJob.insideresultsL = sector.getInsideMatrixL(); cYKJob.insideresultsS = sector.getInsideMatrixS(); // adding outside jobresults while (current.above != null) { current = current.above; cYKJob.addAboveS(current, true); cYKJob.addAboveF(current, true); } current = sector; while (current.diagabove != null) { current = current.diagabove; cYKJob.addDiagAboveS(current, true); cYKJob.addDiagAboveF(current, true); } // adding inside jobresults // 1. adding "far vertical" = "below" current = sector; while (current.diagbelow != null) { // seek to bottom job in sector's diag column current = current.diagbelow; } // add this one: S, inside cYKJob.addBelowS(current, false); // add all above's of this one while (current.above != null) { current = current.above; cYKJob.addBelowS(current, false); } // 2. adding "far diagonal" = "diagbelow" current = sector; while (current.below != null) { // seek to bottom job in sector's column current = current.below; } // add this one: L, inside cYKJob.addDiagBelowL(current, false); // add all diagabove's of this one while (current.diagabove != null) { current = current.diagabove; cYKJob.addDiagBelowL(current, false); } // adding F values current = sector.above; if (current != null) { for (int i = 0; i < sector.dim; i++) { cYKJob.setOutsideVertF(current, i, tmp); cYKJob.setOutsideVertL(current, i, tmp); } } current = sector.diagabove; if (current != null) { for (int i = 0; i < sector.dim; i++) { cYKJob.setOutsideDiagF(current, i, tmp); cYKJob.setOutsideDiagL(current, i, tmp); } Sector other = current.above; if (other != null) { cYKJob.specialF.copyFrom(sector.diagabove.above .getMatrixOutsideFTpVal(0, 0, tmp)); // bottom corner // this time cYKJob.specialL.copyFrom(sector.diagabove.above .getMatrixOutsideLTpVal(0, 0, tmp)); } } current = sector.above; if (current != null) { } cYKJob.setData(sector.dim, sector.getMini(), sector.getMinj(), sector.seqlength, prob); cYKJob.basepairs = sector.getBasePairs(); if(sector.diffbp){ cYKJob.basepairs2 = sector.getBasePairs2(); cYKJob.setDiffBasepairs(true); } return cYKJob; } private CYKJob createExpectationJobFromSector(Sector sector) { PointRes tmp = new PointRes(0, 0); CYKJob cYKJob = new CYKJob(sector.sectorid, sector.dim, 2); Sector current = sector; cYKJob.insideresultsS = sector.getBasePairs(); // own matrix basepairs while (current.below != null) { current = current.below; cYKJob.addBelowE(current); } current = sector; while (current.diagbelow != null) { current = current.diagbelow; cYKJob.addDiagBelowE(current); } current = sector.below; if (current != null) { for (int i = 0; i < sector.dim; i++) { cYKJob.setExpectationVertE(current, i, tmp); } } current = sector.diagbelow; if (current != null) { for (int i = 0; i < sector.dim; i++) { cYKJob.setExpectationDiagE(current, i, tmp); } Sector other = current.below; if (other != null) { cYKJob.specialF.copyFrom(sector.diagbelow.below .getMatrixExpectationTpVal(sector.dim - 1, sector.dim - 1, tmp)); } } cYKJob.setData(sector.dim, sector.getMini(), sector.getMinj(), sector.seqlength, prob); return cYKJob; } public Sector findSector(int sector) { Sector current = this.bottom; while (current.sectorid != sector) { current = current.next; } return current; } private Sector findBottom() { Sector current = this.top; while (current.below != null) { current = current.below; } return current; } /** * @return the top */ public Sector getTop() { return top; } }