/*
* #%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.matrix.model.compressmatrix;
import org.gitools.api.analysis.IProgressMonitor;
import org.gitools.api.matrix.IMatrix;
import org.gitools.api.matrix.IMatrixLayer;
import org.gitools.matrix.MatrixUtils;
import java.util.HashMap;
import java.util.Map;
public class MatrixConversion extends AbstractCompressor {
public CompressMatrix convert(IMatrix inputMatrix, IProgressMonitor progressMonitor) throws Exception {
if (inputMatrix instanceof CompressMatrix) {
return (CompressMatrix) inputMatrix;
}
initialize(new MatrixReader(inputMatrix, progressMonitor));
CompressDimension rows = getRows();
CompressDimension columns = getColumns();
Map<Integer, CompressRow> values = new HashMap<>(inputMatrix.getRows().size());
progressMonitor.begin("Compressing rows...", rows.size());
int totalProperties = inputMatrix.getLayers().size();
for (int r = 0; r < rows.size(); r++) {
NotCompressRow notCompressRow = new NotCompressRow(r, totalProperties, columns);
String rowId = rows.getLabel(r);
int row = inputMatrix.getRows().indexOf(rowId);
for (int c = 0; c < columns.size(); c++) {
String columnId = columns.getLabel(c);
int column = inputMatrix.getColumns().indexOf(columnId);
StringBuilder line = new StringBuilder(totalProperties * 8);
line.append(inputMatrix.getColumns().getLabel(column)).append(SEPARATOR);
line.append(inputMatrix.getRows().getLabel(row)).append(SEPARATOR);
boolean allNull = true;
for (IMatrixLayer layer : inputMatrix.getLayers()) {
Object value = inputMatrix.get(layer, rowId, columnId);
if (value == null) {
line.append(SEPARATOR);
} else {
line.append(MatrixUtils.doubleValue(value)).append(SEPARATOR);
allNull = false;
}
}
if (!allNull) {
notCompressRow.append(line.toString());
}
}
values.put(r, compressRow(notCompressRow));
progressMonitor.worked(1);
if (progressMonitor.isCancelled()) {
throw new RuntimeException("Cancelled by the user");
}
}
return new CompressMatrix(
getRows(),
getColumns(),
getDictionary(),
getHeader(),
values
);
}
private static class MatrixReader implements IMatrixReader {
private int numProperties;
private int row;
private int col;
private IMatrix matrix;
private IProgressMonitor progressMonitor;
private MatrixReader(IMatrix matrix, IProgressMonitor progressMonitor) {
progressMonitor.begin("Preparing compression...", matrix.getRows().size());
this.matrix = matrix;
this.row = -1;
this.col = -1;
this.numProperties = matrix.getLayers().size();
this.progressMonitor = progressMonitor;
}
@Override
public String[] readNext() {
String[] values = new String[numProperties + 2];
if (row == matrix.getRows().size()) {
return null;
}
if (row == -1) {
for (int i = 0; i < numProperties; i++) {
values[0] = "column";
values[1] = "row";
values[i + 2] = matrix.getLayers().get(i).getId();
}
row++;
col++;
} else {
for (int i = 0; i < numProperties; i++) {
values[0] = matrix.getColumns().getLabel(col);
values[1] = matrix.getRows().getLabel(row);
values[i + 2] = Double.toString(MatrixUtils.doubleValue(matrix.get(matrix.getLayers().get(i), values[1], values[0])));
}
col++;
}
if (col == matrix.getColumns().size()) {
row++;
col = 0;
progressMonitor.worked(1);
if (progressMonitor.isCancelled()) {
throw new RuntimeException("Cancelled by the user");
}
}
return values;
}
@Override
public void close() {
}
}
}