001 /* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2013 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029 package edu.wisc.ssec.mcidasv.data.hydra; 030 031 import ucar.nc2.*; 032 import ucar.nc2.ncml.NcMLReader; 033 import ucar.ma2.*; 034 035 import java.util.HashMap; 036 import java.util.List; 037 import java.util.ArrayList; 038 import java.util.Iterator; 039 import java.net.URL; 040 import java.io.InputStream; 041 import java.io.ByteArrayInputStream; 042 043 import org.jdom2.input.SAXBuilder; 044 import org.jdom2.output.XMLOutputter; 045 import org.jdom2.Document; 046 import org.jdom2.Element; 047 048 049 public class NetCDFFile implements MultiDimensionReader { 050 051 HashMap<String, Variable> varMap = new HashMap<String, Variable>(); 052 HashMap<String, String[]> varDimNames = new HashMap<String, String[]>(); 053 HashMap<String, int[]> varDimLengths = new HashMap<String, int[]>(); 054 HashMap<String, Class> varDataType = new HashMap<String, Class>(); 055 HashMap<String, String> varUnits = new HashMap<String, String>(); 056 057 NetcdfFile ncfile = null; 058 059 public static NetCDFFile makeUnion(String filename, String other) throws Exception { 060 Object obj = new Object(); 061 URL url = obj.getClass().getResource("/edu/wisc/ssec/mcidasv/data/hydra/resources/union.ncml"); 062 SAXBuilder builder = new SAXBuilder(false); 063 Document doc = null; 064 065 try { 066 doc = builder.build(url); 067 } catch (Exception e) { 068 e.printStackTrace(); 069 } 070 Element root = doc.getRootElement(); 071 072 List list = root.getChildren(); 073 074 list = ((Element)list.get(1)).getChildren(); 075 076 org.jdom2.Attribute attr1 = (org.jdom2.Attribute) (((Element)list.get(0)).getAttributes()).get(0); 077 attr1.setValue(filename); 078 079 org.jdom2.Attribute attr2 = (org.jdom2.Attribute) (((Element)list.get(1)).getAttributes()).get(0); 080 attr2.setValue(other); 081 082 XMLOutputter xmlOut = new XMLOutputter(); 083 String newStr = xmlOut.outputString(doc); 084 ByteArrayInputStream is = new ByteArrayInputStream(newStr.getBytes()); 085 return new NetCDFFile(is); 086 } 087 088 public NetCDFFile(InputStream is) throws Exception { 089 ncfile = NcMLReader.readNcML(is, null); 090 init(); 091 } 092 093 public NetCDFFile(String filename) throws Exception { 094 if (filename.endsWith(".ncml")) { 095 java.io.FileReader rdr = new java.io.FileReader(filename); 096 ncfile = NcMLReader.readNcML(rdr, null); 097 } 098 else { 099 ncfile = NetcdfFile.open(filename); 100 } 101 init(); 102 } 103 104 public NetCDFFile(String filename, org.jdom2.Element root) throws Exception { 105 ncfile = NcMLReader.readNcML(filename, root, null); 106 init(); 107 } 108 109 private void init() throws Exception { 110 Iterator varIter = ncfile.getVariables().iterator(); 111 while(varIter.hasNext()) { 112 Variable var = (Variable) varIter.next(); 113 114 if (var instanceof Structure) { 115 analyzeStructure((Structure) var); 116 continue; 117 } 118 119 int rank = var.getRank(); 120 String varName = var.getFullName(); 121 varMap.put(varName, var); 122 Iterator dimIter = var.getDimensions().iterator(); 123 String[] dimNames = new String[rank]; 124 int[] dimLengths = new int[rank]; 125 int cnt = 0; 126 while(dimIter.hasNext()) { 127 Dimension dim = (Dimension) dimIter.next(); 128 String dim_name = dim.getShortName(); 129 if (dim_name == null) dim_name = "dim"+cnt; 130 dimNames[cnt] = dim_name; 131 dimLengths[cnt] = dim.getLength(); 132 cnt++; 133 } 134 varDimNames.put(varName, dimNames); 135 varDimLengths.put(varName, dimLengths); 136 varDataType.put(varName, var.getDataType().getPrimitiveClassType()); 137 138 Attribute attr = var.findAttribute("units"); 139 if (attr != null) { 140 String unitStr = attr.getStringValue(); 141 varUnits.put(varName, unitStr); 142 } 143 } 144 } 145 146 void analyzeStructure(Structure var) throws Exception { 147 if ((var.getShape()).length == 0) { 148 return; 149 } 150 String varName = var.getFullName(); 151 String[] dimNames = new String[2]; 152 int[] dimLengths = new int[2]; 153 int cnt = 0; 154 dimLengths[0] = (var.getShape())[0]; 155 dimNames[0] = "dim" + cnt; 156 157 cnt++; 158 StructureData sData = var.readStructure(0); 159 List memList = sData.getMembers(); 160 dimLengths[1] = memList.size(); 161 dimNames[1] = "dim" + cnt; 162 163 varDimNames.put(varName, dimNames); 164 varDimLengths.put(varName, dimLengths); 165 varMap.put(varName, var); 166 167 StructureMembers sMembers = sData.getStructureMembers(); 168 Object obj = sData.getScalarObject(sMembers.getMember(0)); 169 varDataType.put(varName, obj.getClass()); 170 } 171 172 public Class getArrayType(String array_name) { 173 return varDataType.get(array_name); 174 } 175 176 public String[] getDimensionNames(String array_name) { 177 return varDimNames.get(array_name); 178 } 179 180 public int[] getDimensionLengths(String array_name) { 181 return varDimLengths.get(array_name); 182 } 183 184 public String getArrayUnitString(String array_name) { 185 return varUnits.get(array_name); 186 } 187 188 public int getDimensionLength(String dimName) { 189 Dimension dim = ncfile.findDimension(dimName); 190 if (dim != null) { 191 return dim.getLength(); 192 } 193 else { 194 return -1; 195 } 196 } 197 198 public float[] getFloatArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 199 return (float[]) readArray(array_name, start, count, stride); 200 } 201 202 public int[] getIntArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 203 return (int[]) readArray(array_name, start, count, stride); 204 } 205 206 public double[] getDoubleArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 207 return (double[]) readArray(array_name, start, count, stride); 208 } 209 210 public short[] getShortArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 211 return (short[]) readArray(array_name, start, count, stride); 212 } 213 214 public byte[] getByteArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 215 return (byte[]) readArray(array_name, start, count, stride); 216 } 217 218 public Object getArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 219 return readArray(array_name, start, count, stride); 220 } 221 222 protected synchronized Object readArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 223 Variable var = varMap.get(array_name); 224 if (var instanceof Structure) { 225 Array array = Array.factory(getArrayType(array_name), count); 226 Index2D idx = new Index2D(count); 227 for (int i=0; i<count[0]; i++) { 228 StructureData sData = ((Structure)var).readStructure(start[0]+i); 229 StructureMembers sMembers = sData.getStructureMembers(); 230 for (int j=0; j<count[1]; j++) { 231 Object obj = sData.getScalarObject(sMembers.getMember(start[1]+j)); 232 idx.set(i,j); 233 array.setObject(idx, obj); 234 } 235 } 236 return array.copyTo1DJavaArray(); 237 } 238 else { 239 ArrayList rangeList = new ArrayList(); 240 for (int i=0;i<start.length;i++) { 241 Range rng = new Range(start[i], start[i]+(count[i]-1)*stride[i], stride[i]); 242 rangeList.add(i, rng); 243 } 244 Array array = var.read(rangeList); 245 return array.copyTo1DJavaArray(); 246 } 247 } 248 249 public HDFArray getGlobalAttribute(String attr_name) throws Exception { 250 throw new Exception("NetCDFFile.getGlobalAttributes: Unimplemented"); 251 } 252 253 public HDFArray getArrayAttribute(String array_name, String attr_name) throws Exception { 254 Object array = null; 255 DataType dataType = null; 256 257 Variable var = varMap.get(array_name); 258 if (var != null) { 259 Attribute attr = var.findAttribute(attr_name); 260 if (attr != null) { 261 Array attrVals = attr.getValues(); 262 dataType = attr.getDataType(); 263 array = attrVals.copyTo1DJavaArray(); 264 } 265 } 266 267 if (array == null) { 268 return null; 269 } 270 271 HDFArray harray = null; 272 273 if (dataType.getPrimitiveClassType() == Float.TYPE) { 274 harray = HDFArray.make((float[])array); 275 } 276 else if (dataType.getPrimitiveClassType() == Double.TYPE) { 277 harray = HDFArray.make((double[])array); 278 } 279 else if (dataType == DataType.STRING) { 280 harray = HDFArray.make((String[])array); 281 } 282 else if (dataType.getPrimitiveClassType() == Short.TYPE) { 283 harray = HDFArray.make((short[])array); 284 } 285 else if (dataType.getPrimitiveClassType() == Integer.TYPE) { 286 harray = HDFArray.make((int[])array); 287 } 288 return harray; 289 } 290 291 public void close() throws Exception { 292 ncfile.close(); 293 } 294 295 public HashMap getVarMap() { 296 return varMap; 297 } 298 299 public boolean hasArray(String name) { 300 if (varMap.get(name) == null) { 301 return false; 302 } else { 303 return true; 304 } 305 } 306 307 public boolean hasDimension(String name) { 308 if (ncfile.findDimension(name) != null) { 309 return true; 310 } 311 else { 312 return false; 313 } 314 } 315 316 public NetcdfFile getNetCDFFile() { 317 return ncfile; 318 } 319 320 public static void main(String[] args) throws Exception { 321 NetCDFFile ncfile = new NetCDFFile(args[0]); 322 ncfile.close(); 323 } 324 }