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