001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the files COPYING and Copyright.html. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * Or, see https://support.hdfgroup.org/products/licenses.html * 011 * If you do not have access to either file, you may request a copy from * 012 * help@hdfgroup.org. * 013 ****************************************************************************/ 014 015package hdf.object.nc2; 016 017import java.util.List; 018import java.util.Vector; 019 020import hdf.object.Dataset; 021import hdf.object.Datatype; 022import hdf.object.FileFormat; 023import hdf.object.Group; 024import hdf.object.HObject; 025import hdf.object.ScalarDS; 026import ucar.ma2.DataType; 027import ucar.nc2.Variable; 028 029/** 030 * NC2Dataset describes an multi-dimension array of HDF5 scalar or atomic data 031 * types, such as byte, int, short, long, float, double and string, and 032 * operations performed on the scalar dataset 033 * <p> 034 * The library predefines a modest number of datatypes. For details, read <a 035 * href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/HDF5_Users_Guide/Datatypes/HDF5_Datatypes.htm">HDF5 Datatypes</a> 036 * 037 * @version 1.1 9/4/2007 038 * @author Peter X. Cao 039 */ 040public class NC2Dataset extends ScalarDS { 041 private static final long serialVersionUID = -6031051694304457461L; 042 043 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NC2Dataset.class); 044 045 /** tag for netCDF datasets. 046 * HDF4 library supports netCDF version 2.3.2. It only supports SDS APIs. 047 */ 048 // magic number for netCDF: "C(67) D(68) F(70) '\001'" 049 public static final int DFTAG_NDG_NETCDF = 67687001; 050 051 /** 052 * The list of attributes of this data object. Members of the list are 053 * instance of Attribute. 054 */ 055 @SuppressWarnings("rawtypes") 056 private List attributeList; 057 058 private Variable nativeDataset; 059 060 /** 061 * Constructs an NC2Dataset object with specific netcdf variable. 062 * 063 * @param fileFormat 064 * the netcdf file. 065 * @param ncDataset 066 * the netcdf variable. 067 * @param oid 068 * the unique identifier of this data object. 069 */ 070 public NC2Dataset(FileFormat fileFormat, Variable ncDataset, long[] oid) { 071 super(fileFormat, ncDataset.getName(), HObject.SEPARATOR, oid); 072 unsignedConverted = false; 073 nativeDataset = ncDataset; 074 } 075 076 /* 077 * (non-Javadoc) 078 * @see hdf.object.DataFormat#hasAttribute() 079 */ 080 @Override 081 public boolean hasAttribute() { 082 return false; 083 } 084 085 // Implementing Dataset 086 @Override 087 public Dataset copy(Group pgroup, String dstName, long[] dims, Object buff) 088 throws Exception { 089 // not supported 090 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 091 } 092 093 // implementing Dataset 094 @Override 095 public byte[] readBytes() throws Exception { 096 // not supported 097 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 098 } 099 100 // Implementing DataFormat 101 @Override 102 public Object read() throws Exception { 103 Object theData = null; 104 105 if (nativeDataset == null) { 106 return null; 107 } 108 109 int[] origin = new int[rank]; 110 int[] shape = new int[rank]; 111 112 for (int i = 0; i < rank; i++) { 113 origin[i] = (int) startDims[i]; 114 shape[i] = (int) selectedDims[i]; 115 log.trace("read(): origin-shape [{}]={}-{}", i, origin[i], shape[i]); 116 } 117 118 ucar.ma2.Array ncArray = null; 119 120 try { 121 ncArray = nativeDataset.read(origin, shape); 122 } 123 catch (Exception ex) { 124 ncArray = nativeDataset.read(); 125 } 126 Object oneD = ncArray.copyTo1DJavaArray(); 127 128 if (oneD == null) { 129 return null; 130 } 131 132 if (oneD.getClass().getName().startsWith("[C")) { 133 char[] charA = (char[]) oneD; 134 int nCols = (int) selectedDims[selectedIndex[1]]; 135 int nRows = (int) selectedDims[selectedIndex[0]]; 136 137 String[] strA = new String[nRows]; 138 String allStr = new String(charA); 139 140 int indx0 = 0; 141 for (int i = 0; i < nRows; i++) { 142 indx0 = i * nCols; 143 strA[i] = allStr.substring(indx0, indx0 + nCols); 144 } 145 theData = strA; 146 } 147 else { 148 theData = oneD; 149 } 150 151 return theData; 152 } 153 154 // Implementing DataFormat 155 @Override 156 public void write(Object buf) throws Exception { 157 // not supported 158 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 159 } 160 161 // Implementing DataFormat 162 @Override 163 public List getMetadata() throws Exception { 164 if (attributeList != null) { 165 return attributeList; 166 } 167 168 if (nativeDataset == null) { 169 return (attributeList = null); 170 } 171 172 List ncAttrList = nativeDataset.getAttributes(); 173 if (ncAttrList == null) { 174 return (attributeList = null); 175 } 176 177 int n = ncAttrList.size(); 178 attributeList = new Vector(n); 179 ucar.nc2.Attribute ncAttr = null; 180 for (int i = 0; i < n; i++) { 181 ncAttr = (ucar.nc2.Attribute) ncAttrList.get(i); 182 log.trace("getMetadata(): Attribute[{}]:{}", i, ncAttr.toString()); 183 attributeList.add(NC2File.convertAttribute(this, ncAttr)); 184 } 185 186 return attributeList; 187 } 188 189 // implementing DataFormat 190 @Override 191 public void writeMetadata(Object info) throws Exception { 192 // not supported 193 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 194 } 195 196 // implementing DataFormat 197 @Override 198 public void removeMetadata(Object info) throws Exception { 199 // not supported 200 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 201 } 202 203 // implementing DataFormat 204 @Override 205 public void updateMetadata(Object info) throws Exception { 206 // not supported 207 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 208 } 209 210 // Implementing HObject 211 @Override 212 public long open() { 213 return -1; 214 } 215 216 // Implementing HObject 217 @Override 218 public void close(long did) { 219 } 220 221 /** 222 * Retrieve and initialize dimensions and member information. 223 */ 224 @Override 225 public void init() { 226 if (nativeDataset == null) { 227 return; 228 } 229 230 if (inited) { 231 return; // already called. Initialize only once 232 } 233 234 isText = nativeDataset.getDataType().equals(DataType.STRING); 235 boolean isChar = nativeDataset.getDataType().equals(DataType.CHAR); 236 237 rank = nativeDataset.getRank(); 238 log.trace("init(): rank:{}", rank); 239 240 if (rank == 0) { 241 // a scalar data point 242 rank = 1; 243 dims = new long[1]; 244 dims[0] = 1; 245 } 246 else { 247 dims = new long[rank]; 248 for (int i = 0; i < rank; i++) { 249 dims[i] = (nativeDataset.getDimension(i).getLength()); 250 } 251 } 252 253 startDims = new long[rank]; 254 selectedDims = new long[rank]; 255 for (int i = 0; i < rank; i++) { 256 startDims[i] = 0; 257 selectedDims[i] = 1; 258 } 259 260 if (rank == 1) { 261 selectedIndex[0] = 0; 262 selectedDims[0] = dims[0]; 263 } 264 else if (rank == 2) { 265 selectedIndex[0] = 0; 266 selectedIndex[1] = 1; 267 selectedDims[0] = dims[0]; 268 selectedDims[1] = dims[1]; 269 } 270 else if (rank > 2) { 271 selectedIndex[0] = 0; 272 selectedIndex[1] = 1; 273 selectedIndex[2] = 2; 274 selectedDims[0] = dims[0]; 275 selectedDims[1] = dims[1]; 276 } 277 278 if ((rank > 1) && isText) { 279 selectedDims[1] = 1; 280 } 281 282 inited = true; 283 } 284 285 // Implementing ScalarDS 286 @Override 287 public byte[][] getPalette() { 288 if (palette == null) { 289 palette = readPalette(0); 290 } 291 292 return palette; 293 } 294 295 /** 296 * read specific image palette from file. 297 * 298 * @param idx 299 * the palette index to read 300 * @return the palette data into two-dimension byte array, byte[3][256] 301 */ 302 @Override 303 public byte[][] readPalette(int idx) { 304 return null; 305 } 306 307 /** 308 * Creates a new dataset. 309 * 310 * @param name 311 * the name of the dataset to create. 312 * @param pgroup 313 * the parent group of the new dataset. 314 * @param type 315 * the datatype of the dataset. 316 * @param dims 317 * the dimension size of the dataset. 318 * @param maxdims 319 * the max dimension size of the dataset. 320 * @param chunks 321 * the chunk size of the dataset. 322 * @param gzip 323 * the level of the gzip compression. 324 * @param data 325 * the array of data values. 326 * 327 * @return the new dataset if successful. Otherwise returns null. 328 * 329 * @throws Exception 330 * if there is an error 331 */ 332 public static NC2Dataset create(String name, Group pgroup, Datatype type, 333 long[] dims, long[] maxdims, long[] chunks, int gzip, Object data) 334 throws Exception { 335 // not supported 336 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 337 } 338 339 /** 340 * returns the byte array of palette refs. returns null if there is no 341 * palette attribute attached to this dataset. 342 */ 343 @Override 344 public byte[] getPaletteRefs() { 345 return null; 346 } 347 348 // implementing ScalarDS 349 @Override 350 public Datatype getDatatype() { 351 if (datatype == null) { 352 try { 353 datatype = new NC2Datatype(nativeDataset.getDataType()); 354 } 355 catch (Exception ex) { 356 datatype = null; 357 } 358 } 359 360 return datatype; 361 } 362 363 /** 364 * Sets the name of the data object. 365 * <p> 366 * 367 * @param newName 368 * the new name of the object. 369 */ 370 @Override 371 public void setName(String newName) throws Exception { 372 // not supported 373 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 374 } 375 376 //Implementing DataFormat 377 public List getMetadata(int... attrPropList) throws Exception { 378 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 379 } 380 381}