/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.core.operation.geneList; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.Callable; import edu.yu.einstein.genplay.core.operation.Operation; import edu.yu.einstein.genplay.core.operation.geneList.distanceCalculator.DistanceCalculator; import edu.yu.einstein.genplay.core.operationPool.OperationPool; import edu.yu.einstein.genplay.dataStructure.gene.Gene; import edu.yu.einstein.genplay.dataStructure.list.genomeWideList.geneList.GeneList; import edu.yu.einstein.genplay.dataStructure.list.listView.ListView; /** * Computes the distance between closest genes from two {@link GeneList} * The position to be used as a reference (ie: start / middle / stop of a gene) * must be specified by the user. * @author Chirag Gorasia * @version 0.1 */ public class GLODistanceCalculator implements Operation<long[][]>{ private final GeneList geneList1; // input GeneList private final GeneList geneList2; // input GeneList private final int selectionCase; // selection type private boolean stopped = false; // true if the operation must be stopped private static final int POSITIVE_START_START = 1; private static final int POSITIVE_START_MIDDLE = 2; private static final int POSITIVE_START_STOP = 3; private static final int POSITIVE_MIDDLE_START = 4; private static final int POSITIVE_MIDDLE_MIDDLE = 5; private static final int POSITIVE_MIDDLE_STOP = 6; private static final int POSITIVE_STOP_START = 7; private static final int POSITIVE_STOP_MIDDLE = 8; private static final int POSITIVE_STOP_STOP = 9; private static final int NEGATIVE_START_START = 10; private static final int NEGATIVE_START_MIDDLE = 11; private static final int NEGATIVE_START_STOP = 12; private static final int NEGATIVE_MIDDLE_START = 13; private static final int NEGATIVE_MIDDLE_MIDDLE = 14; private static final int NEGATIVE_MIDDLE_STOP = 15; private static final int NEGATIVE_STOP_START = 16; private static final int NEGATIVE_STOP_MIDDLE = 17; private static final int NEGATIVE_STOP_STOP = 18; private static final int BOTH_RELATIVE_START_START = 19; private static final int BOTH_RELATIVE_START_MIDDLE = 20; private static final int BOTH_RELATIVE_START_STOP = 21; private static final int BOTH_RELATIVE_MIDDLE_START = 22; private static final int BOTH_RELATIVE_MIDDLE_MIDDLE = 23; private static final int BOTH_RELATIVE_MIDDLE_STOP = 24; private static final int BOTH_RELATIVE_STOP_START = 25; private static final int BOTH_RELATIVE_STOP_MIDDLE = 26; private static final int BOTH_RELATIVE_STOP_STOP = 27; private static final int BOTH_ABSOLUTE_START_START = 28; private static final int BOTH_ABSOLUTE_START_MIDDLE = 29; private static final int BOTH_ABSOLUTE_START_STOP = 30; private static final int BOTH_ABSOLUTE_MIDDLE_START = 31; private static final int BOTH_ABSOLUTE_MIDDLE_MIDDLE = 32; private static final int BOTH_ABSOLUTE_MIDDLE_STOP = 33; private static final int BOTH_ABSOLUTE_STOP_START = 34; private static final int BOTH_ABSOLUTE_STOP_MIDDLE = 35; private static final int BOTH_ABSOLUTE_STOP_STOP = 36; /** * Creates an instance of {@link GLODistanceCalculator} * @param geneList1 a {@link GeneList} * @param geneList2 a second {@link GeneList} * @param selectionCase selection type */ public GLODistanceCalculator(GeneList geneList1, GeneList geneList2, int selectionCase) { this.geneList1 = geneList1; this.geneList2 = geneList2; this.selectionCase = selectionCase; } @Override public long[][] compute() throws Exception { long[][] result = new long[geneList1.size()][]; final OperationPool op = OperationPool.getInstance(); final Collection<Callable<long[]>> threadList = new ArrayList<Callable<long[]>>(); for (int i = 0; i < geneList1.size(); i++) { final int chromoindex = i; Callable<long[]> currentThread = new Callable<long[]>() { @Override public long[] call() throws Exception { long[] chromoresult = new long[geneList1.get(chromoindex).size()]; if ((geneList1 != null) && (geneList2 != null)) { chromoresult = handleCases(geneList1.get(chromoindex), geneList2, chromoindex); } // tell the operation pool that a chromosome is done op.notifyDone(); return chromoresult; } }; threadList.add(currentThread); } if (op.startPool(threadList) == null) { return null; } int i = 0; for (long[] currentResult: op.startPool(threadList)) { if (currentResult != null) { result[i++] = currentResult; } } return result; } @Override public String getDescription() { return "Operation: Distance Calculation"; } @Override public String getProcessingDescription() { return "Calculating Distance"; } @Override public int getStepCount() { return 1; } /** * Method to handle all of the 20 cases to compute the distance * @param firstList * @param secondList * @return a double 2-D array containing distances */ private long[] handleCases(ListView<Gene> firstList, GeneList secondList, int chrindex) { DistanceCalculator dc; int k = 0; long[] distanceByChromosomes = new long[firstList.size()]; long[] distanceArray = new long[firstList.size()]; switch(selectionCase) { case POSITIVE_START_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 0, 0, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_START_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 0, 1, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_START_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 0, 2, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_MIDDLE_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 1, 0, (int)firstList.get(j).getMiddlePosition()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_MIDDLE_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 1, 1, (int)firstList.get(j).getMiddlePosition()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_MIDDLE_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 1, 2, (int)firstList.get(j).getMiddlePosition()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_STOP_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 2, 0, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_STOP_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 2, 1, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case POSITIVE_STOP_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 0, 2, 2, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_START_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 0, 0, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_START_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 0, 1, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_START_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 0, 2, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_MIDDLE_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 1, 0, firstList.get(j).getStart()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_MIDDLE_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 1, 1, (int)firstList.get(j).getMiddlePosition()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_MIDDLE_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 1, 2, (int)firstList.get(j).getMiddlePosition()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_STOP_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 0, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_STOP_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 1, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case NEGATIVE_STOP_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[k++] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_START_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_START_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); if (dc.getClosestDistance() >= 0) { distanceArray[j] = dc.getClosestDistance(); } } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_START_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_MIDDLE_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_MIDDLE_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_MIDDLE_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_STOP_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_STOP_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_RELATIVE_STOP_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_START_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_START_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_START_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_MIDDLE_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_MIDDLE_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_MIDDLE_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_STOP_START: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_STOP_MIDDLE: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; case BOTH_ABSOLUTE_STOP_STOP: for (int j = 0; (j < firstList.size()) && !stopped; j++) { dc = new DistanceCalculator(secondList, chrindex, 1, 2, 2, firstList.get(j).getStop()); distanceArray[j] = dc.getClosestDistance(); } distanceByChromosomes = distanceArray; break; } return distanceByChromosomes; } @Override public void stop() { stopped = true; } }