package org.autoplot.netCDF; import java.io.IOException; import java.nio.channels.WritableByteChannel; import java.util.logging.Level; import java.util.logging.Logger; import org.das2.datum.LoggerManager; import org.das2.util.monitor.NullProgressMonitor; import org.das2.qds.DataSetUtil; import org.das2.qds.QDataSet; import org.autoplot.datasource.DataSetURI; import ucar.ma2.Array; import ucar.ma2.DataType; import ucar.ma2.InvalidRangeException; import ucar.ma2.Section; import ucar.nc2.Dimension; import ucar.nc2.NetcdfFile; import ucar.nc2.ParsedSectionSpec; import ucar.nc2.Variable; import ucar.nc2.iosp.IOServiceProvider; import ucar.nc2.util.CancelTask; import ucar.unidata.io.RandomAccessFile; /** * APIOServiceProvider adapts Autoplot's data model to NetCDF to allow Autoplot * URIs to be read into NetCDF. The property vapuri in the NCML file contains * an Autoplot URI. It's been a while since we've played with this (to prove * the idea), and I'm not sure where example NCML files are found. * * @author jbf */ public class APIOServiceProvider extends AbstractIOSP implements IOServiceProvider { private static final Logger logger= LoggerManager.getLogger("apdss.netcdf"); @Override public boolean isValidFile(RandomAccessFile arg0) throws IOException { return false; // must refer via iosp="org.autoplot.netcdf.APIOServiceProvider" } QDataSet result; String dep0name; public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask arg2) throws IOException { try { String suri= getProperty("vapuri"); if ( suri==null ) throw new IllegalArgumentException("vapuri must be specified in iospParams"); result= DataSetURI.getDataSource( suri ).getDataSet( new NullProgressMonitor() ); Dimension dim; String name = (String) result.property(QDataSet.NAME); if ( name==null ) name="data"; int n = result.length(); dim = new Dimension(name, n, true, true, false); ncfile.addDimension( null, dim ); QDataSet dep0= (QDataSet) result.property( QDataSet.DEPEND_0 ); dep0name=null; if ( dep0!=null ) { dep0name = (String) dep0.property(QDataSet.NAME); if ( dep0name==null ) dep0name="dep0"; dim = new Dimension(dep0name, n, true, true, false); ncfile.addDimension( null, dim ); } if ( dep0!=null ) { Variable var = new Variable( ncfile, null, null, dep0name ); var.setDataType( DataType.DOUBLE ); //TODO: support other types, use info from ncml var.setDimensionsAnonymous( DataSetUtil.qubeDims(result) ); ncfile.addVariable(null, var); } Variable var = new Variable( ncfile, null, null, name ); var.setDataType( DataType.DOUBLE ); //TODO: support other types, use info from ncml var.setDimensionsAnonymous( DataSetUtil.qubeDims(result) ); ncfile.addVariable(null, var); } catch (Throwable t) { logger.log( Level.WARNING, t.getMessage(), t ); throw new IOException("APIOSP.open() failed: "+t.getMessage()); //, t); } } public Array readData(Variable variable, Section section) throws IOException, InvalidRangeException { DataType type = variable.getDataType(); double[] data; String[] sdata = null; Array array; //Construct the Array. if (type.isString()) { //array = Array.factory(type, DataSetUtil.qubeDims(result), sdata); throw new RuntimeException("whoops"); } else { data= new double[result.length()]; for ( int i=0; i