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