/*-
* Copyright 2015 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 java.util.Iterator;
import java.util.List;
import org.eclipse.january.dataset.ILazyDataset;
import org.eclipse.january.dataset.SliceND;
import org.eclipse.january.dataset.SliceNDIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Iteration over views of a (subsampled) ILazyDataset
*
* Used for iterating of images or XY data in a multidimensional dataset
*
* Views will contain SliceFromSeriesMetadata describing there location in the original ILazyDataset,
* as well as in the subsampled view.
*
* If the input ILazyDataset contains SliceFromSeriesMetadata with a SourceInformation object,
* the SourceInformation will be transfered to each view
*
* Wrapper for a SliceNDIterator, but iterating ILazyDatasets rather than slices,
* also adds extra metadata.
*/
public class SliceViewIterator implements ISliceViewIterator{
private static final Logger logger = LoggerFactory.getLogger(SliceViewIterator.class);
private ILazyDataset lazyDataset;
private SliceNDIterator iterator;
private SliceND sampling;
private SourceInformation source;
private int[] axes;
private int count;
private int total;
private boolean next = false;
/**
* Construct a Slice View Iterator
*
* @param lazyDataset - the full dataset
* @param sampling - the specific part to iterate over
* @param axes - the dimensions the correspond to data axes (i.e. length 1 for XY and 2 for an image)
*/
public SliceViewIterator(ILazyDataset lazyDataset, SliceND sampling, int... axes) {
this.lazyDataset = lazyDataset;
this.sampling = sampling != null ? sampling : new SliceND(lazyDataset.getShape());
sampling = sampling == null ? new SliceND(lazyDataset.getShape()) : sampling;
this.iterator = new SliceNDIterator(sampling, axes);
this.axes = axes;
count = 0;
total = calculateTotal(sampling, axes);
next = iterator.hasNext();
SliceFromSeriesMetadata ss = lazyDataset.getFirstMetadata(SliceFromSeriesMetadata.class);
if (ss != null) {
if (ss.getSourceInfo() != null) source = ss.getSourceInfo();
}
}
/**
* Check to see if there is another view
*
* @return if there is another view
*/
@Override
public boolean hasNext(){
return next;
}
/**
* Resets the iterator
*/
public void reset() {
count = 0;
iterator.reset();
next = iterator.hasNext();
}
/**
* Get the current view on the ILazyDataset
*
* @return lazyDataset
*/
@Override
public ILazyDataset next() {
count++;
SliceND current = iterator.getCurrentSlice().clone();
ILazyDataset view = lazyDataset.getSliceView(current);
view.clearMetadata(SliceFromSeriesMetadata.class);
SliceInformation sl = new SliceInformation(current,
iterator.getOutputSlice().clone(), sampling,
axes, total, count);
SliceFromSeriesMetadata m = new SliceFromSeriesMetadata(source, sl);
view.setMetadata(m);
next = iterator.hasNext();
return view;
}
/**
* Get the total number of views to be iterated over
*
* @return total;
*/
public int getTotal(){
return total;
}
/**
* Get the number of the current ILazyDataset
*
* @return current
*/
public int getCurrent(){
return count;
}
/**
* Get the shape of the subsampled view
*
* @return shape
*/
@Override
public int[] getShape(){
return sampling.getShape().clone();
}
private int calculateTotal(SliceND slice, int[] axes) {
int[] nShape = slice.getShape();
int[] dd = axes.clone();
Arrays.sort(dd);
int n = 1;
for (int i = 0; i < nShape.length; i++) {
if (Arrays.binarySearch(dd, i) < 0) n *= nShape[i];
}
return n;
}
@Override
public void remove() {
//TODO throw something?
}
}