/*-
* Copyright (c) 2016 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.analysis.processing.operations;
//import org.apache.commons.lang.ArrayUtils;
import java.util.Arrays;
import org.eclipse.dawnsci.analysis.api.processing.OperationData;
import org.eclipse.dawnsci.analysis.api.processing.OperationException;
import org.eclipse.dawnsci.analysis.api.processing.OperationRank;
import org.eclipse.dawnsci.analysis.dataset.operations.AbstractOperation;
import org.eclipse.dawnsci.analysis.dataset.slicer.SliceFromSeriesMetadata;
import org.eclipse.january.DatasetException;
import org.eclipse.january.IMonitor;
import org.eclipse.january.MetadataException;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.eclipse.january.dataset.DatasetUtils;
import org.eclipse.january.dataset.IDataset;
import org.eclipse.january.dataset.ILazyDataset;
import org.eclipse.january.metadata.AxesMetadata;
import org.eclipse.january.metadata.MetadataFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.ac.diamond.scisoft.analysis.dataset.function.Interpolation2D;
import uk.ac.diamond.scisoft.analysis.dataset.function.Interpolation2D.BicubicInterpolationOutput;
import uk.ac.diamond.scisoft.analysis.io.LoaderFactory;
public class ConcatenatingTwoDatasetsOperation extends AbstractOperation<ConcatenatingTwoDatasetsModel, OperationData> {
private final Logger logger = LoggerFactory.getLogger(ConcatenatingTwoDatasetsOperation.class);
@Override
public String getId() {
return "uk.ac.diamond.scisoft.analysis.processing.operations.ConcatenatingTwoDatasetsOperation";
}
@Override
public OperationData process(IDataset dataset, IMonitor monitor) throws OperationException {
// get series metadata (will not be null), to check we are from the same
// parent and whether we have hit the final image
SliceFromSeriesMetadata ssm = getSliceSeriesMetadata(dataset);
String filePath = model.getFilePath();
int axis = model.getAxis().getAxis();
//get the name of the incoming dataset
String dataName = null;
if (model.getDatasetName().isEmpty()) {
dataName = ssm.getDatasetName();
} else {
dataName = model.getDatasetName();
}
IDataset dataset_new = null;
try {
dataset_new = LoaderFactory.getDataSet(filePath, dataName, monitor);
} catch (NullPointerException e) {
// dataName looks invalid
if (model.getDatasetName().isEmpty()) {
throw new OperationException(this, "Previously used dataset name not found in file");
} else {
throw new OperationException(this, "Dataset name not found in file");
}
} catch (Exception e) {
logger.error("LoaderFactory.getDataSet exception", e);
throw new OperationException(this, e);
}
// get axis metadata
Dataset axes_old0 = null;
Dataset axes_old1 = null;
Dataset axes_new0 = null;
Dataset axes_new1 = null;
Dataset axes_concat0 = null;
Dataset axes_concat1 = null;
try {
AxesMetadata axes_old = dataset.getMetadata(AxesMetadata.class).get(0);
axes_old0 = DatasetUtils.convertToDataset(axes_old.getAxis(0)[0].getSlice());
axes_old1 = DatasetUtils.convertToDataset(axes_old.getAxis(1)[0].getSlice());
AxesMetadata axes_new = dataset_new.getMetadata(AxesMetadata.class).get(0);
axes_new0 = getAxisDataset(axes_new.getAxis(0), axes_old0.getName());
axes_new1 = getAxisDataset(axes_new.getAxis(1), axes_old1.getName());
//ensure we are dealing with 2D datasets, to avoid trouble later
} catch (Exception e) {
// no axes were found which makes concatenation a lot easier!
// System.out.println("Exception: " + e.getMessage());
}
Dataset axes_concat_mean_old0 = null;
Dataset axes_concat_mean_old1 = null;
Dataset axes_concat_mean_new0 = null;
Dataset axes_concat_mean_new1 = null;
if (axes_old0 != null && axes_new0 != null && axes_old1 != null && axes_new1 != null) {
// axes were found, let's concatenate
try {
axes_concat0 = DatasetUtils.concatenate(new IDataset[]{axes_old0, axes_new0}, axis); //ecc
axes_concat1 = DatasetUtils.concatenate(new IDataset[]{axes_old1, axes_new1}, axis); //bcc
if (axis == 1) {
axes_concat_mean_old0 = axes_concat0.mean(1);
axes_concat_mean_old1 = axes_concat1.mean(0);
axes_concat_mean_new0 = axes_concat_mean_old0;
axes_concat_mean_new1 = DatasetFactory.createLinearSpace(axes_concat_mean_old1.getDouble(0), axes_concat_mean_old1.getDouble(axes_concat_mean_old1.getSize()-1), axes_concat_mean_old1.getSize(), Dataset.FLOAT64);
} else {
axes_concat_mean_old0 = axes_concat0.mean(0);
axes_concat_mean_old1 = axes_concat1.mean(1);
axes_concat_mean_new0 = DatasetFactory.createLinearSpace(axes_concat_mean_old0.getDouble(0), axes_concat_mean_old0.getDouble(axes_concat_mean_old0.getSize()-1), axes_concat_mean_old0.getSize(), Dataset.FLOAT64);
axes_concat_mean_new1 = axes_concat_mean_old1;
}
} catch (IllegalArgumentException e) {
// concatenate exception -> abort
e.printStackTrace();
throw new OperationException(this, e.getMessage() + ". Check concatenation axis!");
}
}
Dataset data_concat = null;
try {
data_concat = DatasetUtils.concatenate(new IDataset[]{dataset, dataset_new}, axis);
} catch (IllegalArgumentException e) {
// concatenate exception -> abort
throw new OperationException(this, e);
}
if (axes_old0 != null && axes_new0 != null && axes_old1 != null && axes_new1 != null) {
data_concat = Interpolation2D.bicubicInterpolation(axes_concat_mean_old0, axes_concat_mean_old1, data_concat, axes_concat_mean_new0, axes_concat_mean_new1, BicubicInterpolationOutput.TWOD);
AxesMetadata axma;
try {
axma = MetadataFactory.createMetadata(AxesMetadata.class, 2);
} catch (MetadataException e) {
throw new OperationException(this, e);
}
//restore 2D nature of axes through concatenating the 1D axes
//this will need to be revised when a user wants to use this feature with 1D axes for a 2D dataset!!!
IDataset[] temp = new IDataset[data_concat.getShape()[1]];
Arrays.fill(temp, axes_concat_mean_new0.reshape(new int[]{axes_concat_mean_new0.getSize(), 1}));
Dataset axes_def0 = DatasetUtils.concatenate(temp, 1);
//remove [:,:] from the end of the name
String axes_name_old0 = axes_old0.getName();
axes_def0.setName(axes_name_old0.substring(0, axes_name_old0.length() - 5));
axma.setAxis(0, axes_def0);
temp = new IDataset[data_concat.getShape()[0]];
Arrays.fill(temp, axes_concat_mean_new1.reshape(new int[]{1, axes_concat_mean_new1.getSize()}));
Dataset axes_def1 = DatasetUtils.concatenate(temp, 0);
//remove [:,:] from the end of the name
String axes_name_old1 = axes_old1.getName();
axes_def1.setName(axes_name_old1.substring(0, axes_name_old1.length() - 5));
axma.setAxis(1, axes_def1);
data_concat.addMetadata(axma);
}
SliceFromSeriesMetadata outsmm = ssm.clone();
for (int i = 0; i < ssm.getParent().getRank(); i++) {
if (!outsmm.isDataDimension(i))
outsmm.reducedDimensionToSingular(i);
}
data_concat.addMetadata(outsmm);
data_concat.setName("Concatenated datasets");
return new OperationData(data_concat);
}
@Override
public OperationRank getInputRank() {
return OperationRank.TWO;
}
@Override
public OperationRank getOutputRank() {
return OperationRank.TWO;
}
private Dataset getAxisDataset(ILazyDataset[] datasets, String datasetName) {
datasetName = datasetName.substring(0, datasetName.indexOf('['));
// chop of 'dirpath'
datasetName = datasetName.substring(datasetName.lastIndexOf('/')+1);
// System.out.println("datasetName: " + datasetName);
Dataset rv = null;
for (int i = 0 ; i < datasets.length ; i++) {
// System.out.println(datasets[i].getName());
if (datasets[i].getName().equals(datasetName)) {
try {
rv = DatasetUtils.convertToDataset(datasets[i].getSlice());
} catch (DatasetException e) {
throw new OperationException(this, e);
}
break;
}
}
return rv;
}
}