001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 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 029package edu.wisc.ssec.mcidasv.data.hydra; 030 031import visad.FlatField; 032import visad.VisADException; 033import visad.RealType; 034import visad.SetType; 035import visad.FunctionType; 036import visad.Set; 037import java.rmi.RemoteException; 038import java.util.HashMap; 039import java.util.Iterator; 040import java.util.Map; 041 042public abstract class MultiDimensionAdapter { 043 044 MultiDimensionReader reader = null; 045 Map<String, Object> metadata = null; 046 String arrayName = null; 047 String[] array_dim_names = null; 048 int[] array_dim_lengths = null; 049 int array_rank; 050 Class arrayType; 051 052 Map<String, String> dimNameMap = new HashMap<>(); 053 054 RealType rangeType; 055 056 RangeProcessor rangeProcessor = null; 057 058 public MultiDimensionAdapter() { 059 } 060 061 public MultiDimensionAdapter(MultiDimensionReader reader, Map<String, Object> metadata) { 062 this.reader = reader; 063 this.metadata = metadata; 064 this.init(); 065 } 066 067 public abstract Map<String, double[]> getDefaultSubset(); 068 069 public abstract Set makeDomain(Map<String, double[]> subset) throws Exception; 070 071 private void init() { 072 this.arrayName = (String) metadata.get("array_name"); 073 074 String[] suppliedDimNames = (String[]) metadata.get("array_dimension_names"); 075 if (suppliedDimNames != null) { 076 array_dim_names = suppliedDimNames; 077 } 078 else { 079 array_dim_names = reader.getDimensionNames(arrayName); 080 } 081 082 array_dim_lengths = reader.getDimensionLengths(arrayName); 083 array_rank = array_dim_lengths.length; 084 arrayType = reader.getArrayType(arrayName); 085 086 for (int i=0; i<array_rank; i++) { 087 dimNameMap.put(array_dim_names[i], array_dim_names[i]); 088 } 089 090 Iterator<String> iter = metadata.keySet().iterator(); 091 while (iter.hasNext()) { 092 String key = iter.next(); 093 Object val = metadata.get(key); 094 if (!(val instanceof String)) continue; 095 String name = (String) val; 096 for (int kk=0; kk<array_rank; kk++) { 097 if (array_dim_names[kk].equals(name)) { 098 dimNameMap.put(array_dim_names[kk], key); 099 } 100 } 101 } 102 103 } 104 105 public Subset getIndexes(Map<String, double[]> select) { 106 Subset subset = new Subset(array_rank); 107 int[] start = subset.getStart(); 108 int[] count = subset.getCount(); 109 int[] stride = subset.getStride(); 110 111 Iterator<String> iter = select.keySet().iterator(); 112 while (iter.hasNext()) { 113 String key = iter.next(); 114 String name = (String) metadata.get(key); 115 116 if (name == null) name = key; 117 118 for (int kk=0; kk<array_rank; kk++) { 119 if (array_dim_names[kk].equals(name)) { 120 double[] coords = select.get(key); 121 122 if (array_dim_lengths[kk] == 1) { 123 start[kk] = 0; 124 count[kk] = 1; 125 stride[kk] = 1; 126 } 127 else { 128 start[kk] = (int) coords[0]; 129 count[kk] = (int) ((coords[1] - coords[0])/coords[2] + 1f); 130 stride[kk] = (int) coords[2]; 131 } 132 133 } 134 } 135 } 136 return subset; 137 } 138 139 public FlatField getData(Map<String, double[]> subset) throws Exception { 140 Set domainSet = makeDomain(subset); 141 return makeFlatField(domainSet, subset); 142 } 143 144 private FlatField makeFlatField(Set domainSet, float[][] range) throws VisADException, RemoteException { 145 FlatField f_field = makeFlatField(domainSet); 146 f_field.setSamples(range, false); 147 return f_field; 148 } 149 150 private FlatField makeFlatField(Set domainSet, double[][] range) throws VisADException, RemoteException { 151 FlatField f_field = makeFlatField(domainSet); 152 f_field.setSamples(range, false); 153 return f_field; 154 } 155 156 private FlatField makeFlatField(Set domainSet) throws VisADException, RemoteException { 157 FlatField f_field = new FlatField(new FunctionType(((SetType)domainSet.getType()).getDomain(), rangeType), domainSet); 158 return f_field; 159 } 160 161 public FlatField makeFlatField(Set domainSet, Map<String, double[]> subset) throws Exception { 162 FlatField f_field = null; 163 164 Object range = readArray(subset); 165 166 if (range instanceof float[]) { 167 float[] new_range = processRange((float[]) range, subset); 168 f_field = makeFlatField(domainSet, new float[][] {new_range}); 169 } 170 else if (range instanceof double[]) { 171 double[] new_range = processRange((double[]) range, subset); 172 f_field = makeFlatField(domainSet, new double[][] {new_range}); 173 } 174 else if (range instanceof short[]) { 175 float[] float_range = processRange((short[])range, subset); 176 f_field = makeFlatField(domainSet, new float[][] {float_range}); 177 } 178 else if (range instanceof byte[]) { 179 float[] float_range = processRange((byte[])range, subset); 180 f_field = makeFlatField(domainSet, new float[][] {float_range}); 181 } 182 183 return f_field; 184 } 185 186 public RangeProcessor getRangeProcessor() { 187 return rangeProcessor; 188 } 189 190 public void setRangeProcessor(RangeProcessor rangeProcessor) { 191 this.rangeProcessor = rangeProcessor; 192 } 193 194 public float[] processRange(short[] range, Map<String, double[]> subset) { 195 if (rangeProcessor == null) { 196 float[] f_range = new float[range.length]; 197 for (int i=0; i<range.length;i++) f_range[i] = (float) range[i]; 198 return f_range; 199 } 200 else { 201 return rangeProcessor.processRange(range, subset); 202 } 203 } 204 205 public float[] processRange(byte[] range, Map<String, double[]> subset) { 206 if (rangeProcessor == null) { 207 float[] f_range = new float[range.length]; 208 for (int i=0; i<range.length;i++) f_range[i] = (float) range[i]; 209 return f_range; 210 } 211 else { 212 return rangeProcessor.processRange(range, subset); 213 } 214 } 215 216 public float[] processRange(float[] range, Map<String, double[]> subset) { 217 if (rangeProcessor == null) { 218 return range; 219 } 220 else { 221 return rangeProcessor.processRange(range, subset); 222 } 223 } 224 225 public double[] processRange(double[] range, Map<String, double[]> subset) { 226 if (rangeProcessor == null) { 227 return range; 228 } 229 else { 230 return rangeProcessor.processRange(range, subset); 231 } 232 } 233 234 235 public Object readArray(Map<String, double[]> subset) throws Exception { 236 Subset select = getIndexes(subset); 237 int[] start = select.getStart(); 238 int[] count = select.getCount(); 239 int[] stride = select.getStride(); 240 241 return reader.getArray(arrayName, start, count, stride); 242 } 243 244 public MultiDimensionReader getReader() { 245 return reader; 246 } 247 248 public Map<String, Object> getMetadata() { 249 return metadata; 250 } 251 252 String getArrayName() { 253 return arrayName; 254 } 255 256 public RealType getRangeType() { 257 return rangeType; 258 } 259 260 public Map<String, double[]> getSubsetFromLonLatRect(Map<String, double[]> subset, double minLat, double maxLat, 261 double minLon, double maxLon) { 262 return subset; 263 } 264 265 public Map<String, double[]> getSubsetFromLonLatRect(double minLat, double maxLat, 266 double minLon, double maxLon) { 267 return null; 268 } 269 270 public Map<String, double[]> getSubsetFromLonLatRect(double minLat, double maxLat, 271 double minLon, double maxLon, 272 int xStride, int yStride, int zStride) { 273 return null; 274 } 275 276}