/* * #%L * gitools-core * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * 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/gpl-3.0.html>. * #L% */ package org.gitools.analysis.overlapping; import org.gitools.analysis.AnalysisException; import org.gitools.analysis.AnalysisProcessor; import org.gitools.api.analysis.IProgressMonitor; import org.gitools.api.matrix.IMatrix; import org.gitools.api.matrix.IMatrixDimension; import org.gitools.api.matrix.IMatrixLayer; import org.gitools.api.matrix.IMatrixPosition; import org.gitools.api.resource.ResourceReference; import org.gitools.matrix.model.hashmatrix.HashMatrix; import org.gitools.matrix.model.hashmatrix.HashMatrixDimension; import org.gitools.matrix.model.matrix.element.LayerAdapter; import java.util.Date; import java.util.HashMap; import java.util.Map; import static org.gitools.api.matrix.MatrixDimensionKey.COLUMNS; import static org.gitools.api.matrix.MatrixDimensionKey.ROWS; public class OverlappingProcessor implements AnalysisProcessor { private final OverlappingAnalysis analysis; public OverlappingProcessor(OverlappingAnalysis analysis) { this.analysis = analysis; } @Override public void run(IProgressMonitor monitor) { Date startTime = new Date(); IMatrix data = analysis.getSourceData().get(); IMatrixLayer<Double> layer = data.getLayers().get(analysis.getAttributeName()); if (layer == null) { layer = data.getLayers().iterator().next(); } IMatrixDimension rows = (analysis.isTransposeData() ? data.getDimension(COLUMNS) : data.getDimension(ROWS)); IMatrixDimension columns = (analysis.isTransposeData() ? data.getDimension(ROWS) : data.getDimension(COLUMNS)); monitor.begin("Running Overlapping analysis ...", columns.size() * (columns.size() - 1) / 2); final LayerAdapter<OverlappingResult> adapter = new LayerAdapter<>(OverlappingResult.class); final IMatrix results = new HashMatrix( adapter.getMatrixLayers(), new HashMatrixDimension(ROWS, columns), new HashMatrixDimension(COLUMNS, columns) ); analysis.setCellResults(new ResourceReference<>("results", results)); Map<String, Boolean> x = new HashMap<>(rows.size()); Map<String, Boolean> xna = new HashMap<>(rows.size()); IMatrixPosition positionX = data.newPosition(); IMatrixPosition positionY = data.newPosition(); for (String X : positionX.iterate(columns)) { int rowCount = 0; for (String row : positionX.iterate(rows)) { Double value = transformValue( data.get(layer, positionX), analysis ); if (value == 1.0) { rowCount++; } x.put(row, value == 1.0); xna.put(row, Double.isNaN(value)); } for (String Y : positionY.iterate(columns.from(X))) { if (monitor.isCancelled()) { break; } monitor.info("Overlapping " + X + " with " + Y); int columnCount = 0; int bothCount = 0; for (String row : positionY.iterate(rows)) { double v0 = xna.get(row) ? Double.NaN : (x.get(row) ? 1.0 : 0.0); Double v1 = data.get(layer, positionY); v1 = transformValue(v1, analysis); if (v1 == 1.0) { columnCount++; } if (v0 == 1.0 && v1 == 1.0) { bothCount++; } } adapter.set(results, new OverlappingResult(rowCount, columnCount, bothCount), X, Y); monitor.worked(1); } } analysis.setStartTime(startTime); analysis.setElapsedTime(new Date().getTime() - startTime.getTime()); } private Double transformValue(Double v, OverlappingAnalysis analysis) throws AnalysisException { boolean isNaN = (v == null || Double.isNaN(v)); if (isNaN) { v = (analysis.getReplaceNanValue() == null ? Double.NaN : analysis.getReplaceNanValue()); } if (!isNaN && analysis.isBinaryCutoffEnabled()) { v = analysis.getBinaryCutoffCmp().compare(v, analysis.getBinaryCutoffValue()) ? 1.0 : 0.0; } if (!isNaN && v != 1.0 && v != 0.0) { throw new AnalysisException("Not binary value found"); } return v; } }