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