001/* 002 * $Id: NetCDFFile.java,v 1.21 2011/03/24 16:06:33 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2011 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 031package edu.wisc.ssec.mcidasv.data.hydra; 032 033import ucar.nc2.*; 034import ucar.nc2.ncml.NcMLReader; 035import ucar.ma2.*; 036import java.util.HashMap; 037import java.util.List; 038import java.util.ArrayList; 039import java.util.Iterator; 040import java.net.URL; 041import java.net.URL; 042import java.io.InputStream; 043import java.io.ByteArrayInputStream; 044 045import org.jdom.input.SAXBuilder; 046import org.jdom.output.XMLOutputter; 047import org.jdom.Document; 048import org.jdom.Element; 049 050 051public 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 060 NetcdfFile ncfile = null; 061 062 063 public static NetCDFFile makeUnion(String filename) throws Exception { 064 String other = new String(filename); 065 other = other.replace("obs", "nav"); 066 Object obj = new Object(); 067 URL url = obj.getClass().getResource("/edu/wisc/ssec/mcidasv/data/hydra/resources/union.ncml"); 068 SAXBuilder builder = new SAXBuilder(false); 069 Document doc = null; 070 071 try { 072 doc = builder.build(url); 073 } catch (Exception e) { 074 e.printStackTrace(); 075 } 076 Element root = doc.getRootElement(); 077 078 List list = root.getChildren(); 079 080 list = ((Element)list.get(1)).getChildren(); 081 082 org.jdom.Attribute attr1 = (org.jdom.Attribute) (((Element)list.get(0)).getAttributes()).get(0); 083 attr1.setValue(filename); 084 085 org.jdom.Attribute attr2 = (org.jdom.Attribute) (((Element)list.get(1)).getAttributes()).get(0); 086 attr2.setValue(other); 087 088 XMLOutputter xmlOut = new XMLOutputter(); 089 String newStr = xmlOut.outputString(doc); 090 ByteArrayInputStream is = new ByteArrayInputStream(newStr.getBytes()); 091 return new NetCDFFile(is); 092 } 093 094 public NetCDFFile(InputStream is) throws Exception { 095 ncfile = NcMLReader.readNcML(is, null); 096 init(); 097 } 098 099 public NetCDFFile(String filename) throws Exception { 100 if (filename.endsWith(".ncml")) { 101 java.io.FileReader rdr = new java.io.FileReader(filename); 102 ncfile = NcMLReader.readNcML(rdr, null); 103 } 104 else { 105 ncfile = NetcdfFile.open(filename); 106 } 107 init(); 108 } 109 110 public NetCDFFile(String filename, org.jdom.Element root) throws Exception { 111 ncfile = NcMLReader.readNcML(filename, root, null); 112 init(); 113 } 114 115 private void init() throws Exception { 116 Iterator varIter = ncfile.getVariables().iterator(); 117 while(varIter.hasNext()) { 118 Variable var = (Variable) varIter.next(); 119 120 if (var instanceof Structure) { 121 analyzeStructure((Structure) var); 122 continue; 123 } 124 125 int rank = var.getRank(); 126 String varName = var.getName(); 127 varMap.put(var.getName(), var); 128 Iterator dimIter = var.getDimensions().iterator(); 129 String[] dimNames = new String[rank]; 130 int[] dimLengths = new int[rank]; 131 int cnt = 0; 132 while(dimIter.hasNext()) { 133 Dimension dim = (Dimension) dimIter.next(); 134 String dim_name = dim.getName(); 135 if (dim_name == null) dim_name = "dim"+cnt; 136 dimNames[cnt] = dim_name; 137 dimLengths[cnt] = dim.getLength(); 138 cnt++; 139 } 140 varDimNames.put(varName, dimNames); 141 varDimLengths.put(varName, dimLengths); 142 varDataType.put(varName, var.getDataType().getPrimitiveClassType()); 143 144 Attribute attr = var.findAttribute("units"); 145 if (attr != null) { 146 String unitStr = attr.getStringValue(); 147 varUnits.put(varName, unitStr); 148 } 149 } 150 } 151 152 void analyzeStructure(Structure var) throws Exception { 153 if ((var.getShape()).length == 0) { 154 return; 155 } 156 String varName = var.getName(); 157 String[] dimNames = new String[2]; 158 int[] dimLengths = new int[2]; 159 List vlist = var.getVariables(); 160 int cnt = 0; 161 dimLengths[0] = (var.getShape())[0]; 162 dimNames[0] = "dim"+cnt; 163 164 165 cnt++; 166 StructureData sData = var.readStructure(0); 167 List memList = sData.getMembers(); 168 dimLengths[1] = memList.size(); 169 dimNames[1] = "dim"+cnt; 170 171 varDimNames.put(varName, dimNames); 172 varDimLengths.put(varName, dimLengths); 173 varMap.put(var.getName(), var); 174 175 StructureMembers sMembers = sData.getStructureMembers(); 176 Object obj = sData.getScalarObject(sMembers.getMember(0)); 177 varDataType.put(varName, obj.getClass()); 178 } 179 180 public Class getArrayType(String array_name) { 181 Variable var = varMap.get(array_name); 182 return varDataType.get(array_name); 183 } 184 185 public String[] getDimensionNames(String array_name) { 186 return varDimNames.get(array_name); 187 } 188 189 public int[] getDimensionLengths(String array_name) { 190 return varDimLengths.get(array_name); 191 } 192 193 public String getArrayUnitString(String array_name) { 194 return varUnits.get(array_name); 195 } 196 197 public int getDimensionLength(String dimName) { 198 Dimension dim = ncfile.findDimension(dimName); 199 return dim.getLength(); 200 } 201 202 public float[] getFloatArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 203 return (float[]) readArray(array_name, start, count, stride); 204 } 205 206 public int[] getIntArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 207 return (int[]) readArray(array_name, start, count, stride); 208 } 209 210 public double[] getDoubleArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 211 return (double[]) readArray(array_name, start, count, stride); 212 } 213 214 public short[] getShortArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 215 return (short[]) readArray(array_name, start, count, stride); 216 } 217 218 public byte[] getByteArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 219 return (byte[]) readArray(array_name, start, count, stride); 220 } 221 222 public Object getArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 223 return readArray(array_name, start, count, stride); 224 } 225 226 private synchronized Object readArray(String array_name, int[] start, int[] count, int[] stride) throws Exception { 227 Variable var = varMap.get(array_name); 228 if (var instanceof Structure) { 229 Array array = Array.factory(getArrayType(array_name), count); 230 Index2D idx = new Index2D(count); 231 for (int i=0; i<count[0]; i++) { 232 StructureData sData = ((Structure)var).readStructure(start[0]+i); 233 StructureMembers sMembers = sData.getStructureMembers(); 234 for (int j=0; j<count[1]; j++) { 235 Object obj = sData.getScalarObject(sMembers.getMember(start[1]+j)); 236 idx.set(i,j); 237 array.setObject(idx, obj); 238 } 239 } 240 return array.copyTo1DJavaArray(); 241 } 242 else { 243 ArrayList rangeList = new ArrayList(); 244 for (int i=0;i<start.length;i++) { 245 Range rng = new Range(start[i], start[i]+(count[i]-1)*stride[i], stride[i]); 246 rangeList.add(i, rng); 247 } 248 Array array = var.read(rangeList); 249 return array.copyTo1DJavaArray(); 250 } 251 } 252 253 public HDFArray getGlobalAttribute(String attr_name) throws Exception { 254 throw new Exception("NetCDFFile.getGlobalAttributes: Unimplemented"); 255 } 256 257 public HDFArray getArrayAttribute(String array_name, String attr_name) throws Exception { 258 Object array = null; 259 DataType dataType = null; 260 261 Variable var = varMap.get(array_name); 262 if (var != null) { 263 Attribute attr = var.findAttribute(attr_name); 264 if (attr != null) { 265 Array attrVals = attr.getValues(); 266 dataType = attr.getDataType(); 267 array = attrVals.copyTo1DJavaArray(); 268 } 269 } 270 271 if (array == null) { 272 return null; 273 } 274 275 HDFArray harray = null; 276 277 if (dataType.getPrimitiveClassType() == Float.TYPE) { 278 harray = HDFArray.make((float[])array); 279 } 280 else if (dataType.getPrimitiveClassType() == Double.TYPE) { 281 harray = HDFArray.make((double[])array); 282 } 283 else if (dataType == DataType.STRING) { 284 harray = HDFArray.make((String[])array); 285 } 286 else if (dataType.getPrimitiveClassType() == Short.TYPE) { 287 harray = HDFArray.make((short[])array); 288 } 289 else if (dataType.getPrimitiveClassType() == Integer.TYPE) { 290 harray = HDFArray.make((int[])array); 291 } 292 return harray; 293 } 294 295 public void close() throws Exception { 296 ncfile.close(); 297 } 298 299 public HashMap getVarMap() { 300 return varMap; 301 } 302 303 public boolean hasArray(String name) { 304 if (varMap.get(name) == null) { 305 return false; 306 } else { 307 return true; 308 } 309 } 310 311 public NetcdfFile getNetCDFFile() { 312 return ncfile; 313 } 314 315 public static void main(String[] args) throws Exception { 316 NetCDFFile ncfile = new NetCDFFile(args[0]); 317 ncfile.close(); 318 } 319}