/* * Copyright 2011 Diamond Light Source Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package uk.ac.diamond.scisoft.analysis.dataset; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; import java.util.Arrays; import org.eclipse.dawnsci.nexus.NexusException; import org.eclipse.january.IMonitor; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.ILazyDataset; import org.eclipse.january.dataset.LazyDataset; import org.eclipse.january.dataset.SliceND; import org.eclipse.january.io.ILazyLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import gda.data.nexus.extractor.NexusExtractor; import gda.data.nexus.extractor.NexusGroupData; import gda.data.nexus.tree.INexusSourceProvider; import gda.data.nexus.tree.INexusTree; /** * Helper methods for NeXus */ public class Nexus { /** * Setup the logging facilities */ transient private static final Logger logger = LoggerFactory.getLogger(Nexus.class); /** * @param node * @return lazy dataset */ public static ILazyDataset createLazyDataset(INexusTree node) { NexusGroupData groupData = node.getData(); final URL source; final String nodePath; INexusTree top = node; while (top.getParentNode() != null) { top = top.getParentNode(); } if (top instanceof INexusSourceProvider) { source = ((INexusSourceProvider) top).getSource(); } else { source = null; } if (source == null) { logger.error("Source of Nexus tree is not defined"); return null; } final String name = node.getName(); nodePath = node.getNodePathWithClasses(); final int[] trueShape = groupData.dimensions; ILazyDataset groupDataset; if (groupData.getBuffer() == null) { ILazyLoader l = new ILazyLoader() { @Override public boolean isFileReadable() { try { String host = source.getHost(); if (host != null && host.length() > 0 && !host.equals(InetAddress.getLocalHost().getHostName())) return false; } catch (UnknownHostException e) { logger.warn("Problem finding local host so ignoring check", e); } return new File(source.getPath()).canRead(); } @Override public String toString() { return source.getFile() + ":" + nodePath; } @Override public Dataset getDataset(IMonitor mon, SliceND slice) throws IOException { int[] lstart = slice.getStart(); int[] lstep = slice.getStep(); int[] newShape = slice.getShape(); int rank = newShape.length; boolean useSteps = false; int[] size; for (int i = 0; i < rank; i++) { if (lstep[i] != 1) { useSteps = true; break; } } if (useSteps) { // have to get superset of slice as NeXus API's getslab doesn't allow steps size = new int[rank]; for (int i = 0; i < rank; i++) { int last = lstart[i] + (newShape[i]-1)*lstep[i]; // last index if (lstep[i] < 0) { size[i] = lstart[i] - last + 1; lstart[i] = last; } else { size[i] = last - lstart[i] + 1; } } } else { size = newShape; } Dataset d = null; try { NexusGroupData ngd = null; if (!Arrays.equals(trueShape, slice.getSourceShape())) { // if shape was squeezed then need to translate to true slice final int trank = trueShape.length; int[] tstart = new int[trank]; int[] tsize = new int[trank]; int j = 0; for (int i = 0; i < trank; i++) { if (trueShape[i] == 1) { tstart[i] = 0; tsize[i] = 1; } else { tstart[i] = lstart[j]; tsize[i] = size[j]; j++; } } ngd = NexusExtractor.getNexusGroupData(source, nodePath, tstart, tsize, logger.isDebugEnabled()); d = ngd.toDataset(false); d.setShape(size); // squeeze shape back } else { ngd = NexusExtractor.getNexusGroupData(source, nodePath, lstart, size, logger.isDebugEnabled()); d = ngd.toDataset(false); } if (d != null) { if (useSteps) d = d.getSlice(null, null, lstep); // reduce dataset to requested elements d.setName(name); } } catch (NexusException e) { logger.error("Problem with NeXus library: {}", e); } return d; } }; groupDataset = new LazyDataset(name, groupData.getDType(), trueShape.clone(), l); } else { Dataset dataset = groupData.toDataset(false); dataset.setName(name); groupDataset = dataset; } return groupDataset; } }