/* * Copyright (c) 2014, 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 org.eclipse.dawnsci.analysis.dataset.slicer; import java.util.Arrays; import org.apache.commons.lang.ArrayUtils; import org.eclipse.january.DatasetException; import org.eclipse.january.dataset.IDataset; import org.eclipse.january.dataset.IDynamicDataset; import org.eclipse.january.dataset.ILazyDataset; import org.eclipse.january.dataset.Slice; import org.eclipse.january.metadata.OriginMetadata; public class SliceFromSeriesMetadata implements OriginMetadata { private SourceInformation sourceInfo; private SliceInformation sliceInfo; public SliceFromSeriesMetadata(SourceInformation source, SliceInformation slice) { this.sourceInfo = source; this.sliceInfo = slice; } public SliceFromSeriesMetadata(SliceInformation slice) { this.sliceInfo = slice; } public SliceFromSeriesMetadata(SourceInformation source) { this.sourceInfo = source; } @Override public void initialize(int[] shape, int[] maxShape, int[] chunkShape) { } @Override public void initialize(ILazyDataset parent, Slice[] outSlice, int[] dataDims, String filePath, String datasetName) { } public SourceInformation getSourceInfo() { return sourceInfo; } public SliceInformation getSliceInfo() { return sliceInfo; } @Override public SliceFromSeriesMetadata clone() { SourceInformation soi = sourceInfo != null ? sourceInfo.clone() : null; SliceInformation sli = sliceInfo != null ? sliceInfo.clone() : null; return new SliceFromSeriesMetadata(soi, sli); } @Override public int[] getDataDimensions() { return sliceInfo != null ? sliceInfo.getDataDimensions() : null; } @Override public ILazyDataset getParent() { return sourceInfo != null ? sourceInfo.getParent() : null; } @Override public Slice[] getSliceInOutput() { return sliceInfo != null ? sliceInfo.getSliceInOutput() : null; } @Override public String getDatasetName() { return sourceInfo != null ? sourceInfo.getDatasetName() : null; } @Override public String getFilePath() { return sourceInfo != null ? sourceInfo.getFilePath() : null; } @Override public Slice[] getSliceFromInput() { return sliceInfo != null ? sliceInfo.getSliceFromInput() : null; } public int[] getSubSampledShape() { return sliceInfo != null ? sliceInfo.getSubSampledShape() : null; } public int getTotalSlices() { return sliceInfo != null ? sliceInfo.getTotalSlices() : -1; } public boolean isDataDimension(int dim) { return sliceInfo != null ? sliceInfo.isDataDimension(dim) : false; } public void reducedDimensionToSingular(int dim) { if (sliceInfo.isDataDimension(dim)) throw new IllegalArgumentException("Cannot reduce data dimension!"); sliceInfo.reducedDimensionToSingular(dim); } /** * For when external data is a different series of the same data shape. * * Returns the dimensions of the input shape compatible with the series parent, * null if no suitable dimensions found. * * i.e. if parent is [p,q,x,y] and shape is [v,x,y] returns [1,2] * * @param shape * @return datadims */ public int[] getCompatibleDataDimensions(int[] shape) { int[] datadims = getDataDimensions(); int[] oShape = getParent().getShape(); //same rank, dims must be same shape if (shape.length == oShape.length) { for (int i : datadims) { if (shape[i] != oShape[i]) return null; } return datadims.clone(); } boolean suitable = true; for (int i : datadims) { if (i >= shape.length) { suitable = false; break; } if (shape[i] != oShape[i]){ suitable = false; break; } } if (suitable) return datadims.clone(); suitable = true; int[] shift = datadims.clone(); int rankdif = oShape.length-shape.length; for (int i = 0; i < shift.length; i++) shift[i] -=rankdif; for (int i = 0; i < shift.length; i++) { if (shift[i] >= shape.length || shift[i] < 0) { suitable = false; break; } if (shape[shift[i]] != oShape[datadims[i]]){ suitable = false; break; } } if (suitable) return shift; return null; } /** * Returns the slice corresponding to matching slice of parent, currently assumes * rank of input <= rank of parent * * returns null if ds not suitable shape * * i.e. if current slice is [3,4,x,y] and ds has shape [p,q,2] returns [3,4,:] * * @param ds * @return slice * @throws DatasetException */ public IDataset getMatchingSlice(ILazyDataset ds) throws DatasetException { boolean isLive = sourceInfo.isLive(); if (isLive) { if (ds instanceof IDynamicDataset) ((IDynamicDataset)ds).refreshShape(); } int[] oShape = getParent().getShape(); int[] shape = ds.getShape(); int[] datadims = getDataDimensions(); if (Arrays.equals(oShape, shape)){ return ds.getSlice(getSliceFromInput()); } Slice[] oSlices = getSliceFromInput(); Slice[] slices = new Slice[shape.length]; for (int i = 0; i < slices.length && i < oShape.length; i++) { if (ArrayUtils.contains(datadims, i)) { slices[i] = null; } else { if (isLive && shape[i] >= oSlices[i].getStart()) { slices[i] = oSlices[i]; } else if (shape[i] != oShape[i]) { return null; } else { slices[i] = oSlices[i]; } } } return ds.getSlice(slices); } @Override public int[] getDataMaxDimensions() { return null; } @Override public int[] getDataChunkDimensions() { return null; } }