/*-
* 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.List;
import org.eclipse.january.DatasetException;
import org.eclipse.january.dataset.IDataset;
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;
public class SliceBlockIterator implements ISliceViewIterator{
private static final Logger logger = LoggerFactory.getLogger(SliceBlockIterator.class);
private ILazyDataset lazyDataset;
private SliceNDIterator iterator;
private SliceND sampling;
private SourceInformation source;
private int[] axes;
private int count;
private int total;
private int blocks = 10;
private int fastest;
private int subCount;
private IDataset subSet;
private boolean next;
/**
* 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 SliceBlockIterator(ILazyDataset lazyDataset, SliceND sampling, int... axes) {
if (sampling == null) sampling = new SliceND(lazyDataset.getShape());
this.lazyDataset = lazyDataset.getSliceView(sampling);
// this.sampling = sampling != null ? sampling : new SliceND(lazyDataset.getShape());
this.iterator = new SliceNDIterator(sampling, axes);
this.axes = axes;
this.sampling = sampling;
count = 0;
total = calculateTotal(sampling, axes);
Arrays.sort(axes);
for (int i = 0; i < lazyDataset.getRank(); i++){
if (Arrays.binarySearch(axes, i) < 0) fastest = i;
}
subCount = 0;
next = iterator.hasNext();
List<SliceFromSeriesMetadata> sl;
try {
sl = lazyDataset.getMetadata(SliceFromSeriesMetadata.class);
if (sl != null && !sl.isEmpty() && sl.get(0) != null) {
SliceFromSeriesMetadata ss = sl.get(0);
if (ss.getSourceInfo() != null) source = ss.getSourceInfo();
}
} catch (Exception e) {
logger.warn("Lazy dataset contains no source information", e);
}
}
/**
* 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++;
IDataset out = null;
SliceND current = iterator.getCurrentSlice().clone();
if (subCount == 0) {
SliceND c = current.clone();
int max = lazyDataset.getShape()[fastest];
int stop = current.getStop()[fastest];
int newStop = stop + blocks-1;
newStop = newStop > max ? max : newStop;
int start = c.getStart()[fastest];
c.setSlice(fastest, start, newStop, 1);
try {
subSet = lazyDataset.getSlice(c);
} catch (DatasetException e) {
logger.error("Could not get data from lazy dataset", e);
return out;
}
SliceND s = new SliceND(subSet.getShape());
s.setSlice(fastest, 0, 1, 1);
out = subSet.getSliceView(s);
if (subSet.getShape()[fastest] != 1) subCount++;
} else {
SliceND s = new SliceND(subSet.getShape());
s.setSlice(fastest, subCount, subCount+1, 1);
out = subSet.getSliceView(s);
if (subCount == subSet.getShape()[fastest]-1) subCount = 0;
else subCount++;
}
out.clearMetadata(SliceFromSeriesMetadata.class);
SliceInformation sl = new SliceInformation(current,
iterator.getOutputSlice().clone(), sampling,
axes, total, count);
SliceFromSeriesMetadata m = new SliceFromSeriesMetadata(source, sl);
out.setMetadata(m);
next = iterator.hasNext();
return out;
}
/**
* 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?
}
}