/*
* #%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.sort;
import com.google.common.collect.Sets;
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.matrix.model.MatrixLayers;
import org.gitools.matrix.model.hashmatrix.HashMatrix;
import org.gitools.matrix.model.hashmatrix.HashMatrixDimension;
import org.gitools.matrix.model.iterable.PositionMapping;
import java.util.Comparator;
import java.util.Set;
import static org.gitools.api.matrix.MatrixDimensionKey.ROWS;
public class AggregationSortByValueComparator implements Comparator<String> {
private MatrixLayers<IMatrixLayer<Double>> aggregationLayers;
private IMatrix aggregationMatrix;
private final IMatrixDimension sortDimension;
private Set sortIdentifiers;
private final int firstPosition;
/**
* @param matrix data matrix
* @param sortDimension Sorted dimension
* @param sortIdentifiers Identifiers to be sorted (all if empty)
* @param firstPosition Indicate if only sorting selected items, otherwise -1
* @param aggregationDimension Aggregated dimension
* @param aggregationIdentifiers Identifiers to get aggregation data from (all if empty)
* @param progressMonitor monitor
* @param layers Data layers to aggregate and sort (order = relevance)
*/
public AggregationSortByValueComparator(IMatrix matrix, IMatrixDimension sortDimension, Set<String> sortIdentifiers, int firstPosition, IMatrixDimension aggregationDimension, Set<String> aggregationIdentifiers, IProgressMonitor progressMonitor, Iterable<IMatrixLayer<Double>> layers) {
this.sortDimension = sortDimension;
this.sortIdentifiers = sortIdentifiers;
this.firstPosition = firstPosition;
aggregationLayers = new MatrixLayers<>(layers);
aggregationMatrix = new HashMatrix(
aggregationLayers,
new HashMatrixDimension(ROWS, sortIdentifiers)
);
if (sortIdentifiers.isEmpty()) {
sortIdentifiers = Sets.newHashSet(sortDimension);
}
if (aggregationIdentifiers.isEmpty()) {
aggregationIdentifiers = Sets.newHashSet(aggregationDimension);
}
for (IMatrixLayer<Double> layer : layers) {
matrix.newPosition()
.iterate(sortDimension.subset(sortIdentifiers))
.monitor(progressMonitor, "Aggregating values of layer '" + layer.getId() + "'")
.transform(new AggregationFunction(layer, aggregationDimension, aggregationIdentifiers))
.store(
aggregationMatrix,
new PositionMapping().map(sortDimension, ROWS),
aggregationLayers.get(layer.getId())
);
}
}
@Override
public int compare(String idx1, String idx2) {
if (firstPosition > -1) {
// 1. If idx1 or idx2 is not in aggregationMatrix compare position
boolean before1 = sortDimension.indexOf(idx1) < firstPosition;
boolean before2 = sortDimension.indexOf(idx2) < firstPosition;
if (!sortIdentifiers.contains(idx1) && !sortIdentifiers.contains(idx2)) {
if (before1 != before2) {
return before1 ? -1 : 1;
} else {
return 0;
}
} else if (!sortIdentifiers.contains(idx1)) {
return before1 ? -1 : 1;
}
else if (!sortIdentifiers.contains(idx2)) {
return before2 ? 1 : -1;
}
}
// 2. Compare all layers of aggregated items
for (IMatrixLayer<Double> layer : aggregationLayers) {
int compare = layer.getSortDirection().compare(
aggregationMatrix.get(layer, idx1),
aggregationMatrix.get(layer, idx2)
);
if (compare != 0) {
return compare;
}
}
// All the layer are equal
return 0;
}
}