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 java.awt.geom.Rectangle2D;
032 import java.rmi.RemoteException;
033 import java.util.ArrayList;
034 import java.util.HashMap;
035 import java.util.Iterator;
036
037 import visad.CoordinateSystem;
038 import visad.FlatField;
039 import visad.FunctionType;
040 import visad.Gridded2DSet;
041 import visad.Linear1DSet;
042 import visad.Linear2DSet;
043 import visad.Real;
044 import visad.RealTuple;
045 import visad.RealTupleType;
046 import visad.RealType;
047 import visad.SampledSet;
048 import visad.Set;
049 import visad.SetType;
050 import visad.VisADException;
051
052 public class MultiSpectralData extends MultiDimensionAdapter {
053
054 SwathAdapter swathAdapter = null;
055 SpectrumAdapter spectrumAdapter = null;
056 CoordinateSystem cs = null;
057
058 HashMap spectrumSelect = null;
059 HashMap swathSelect = null;
060
061 String sensorName = null;
062 String platformName = null;
063 String paramName = null;
064 String inputParamName = null;
065 String name = null;
066
067 public float init_wavenumber = 919.50f;
068 public String init_bandName = null;
069
070 float[] dataRange = new float[] {180f, 320f};
071
072 boolean hasBandNames = false;
073 ArrayList<String> bandNameList = null;
074 HashMap<String, Float> bandNameMap = null;
075
076
077 public MultiSpectralData(SwathAdapter swathAdapter, SpectrumAdapter spectrumAdapter,
078 String inputParamName, String paramName, String sensorName, String platformName) {
079 this.swathAdapter = swathAdapter;
080 this.spectrumAdapter = spectrumAdapter;
081 this.paramName = paramName;
082 this.inputParamName = inputParamName;
083 this.name = swathAdapter.getArrayName();
084
085 if (spectrumAdapter != null) {
086 this.spectrumSelect = spectrumAdapter.getDefaultSubset();
087 if (spectrumAdapter.hasBandNames()) {
088 hasBandNames = true;
089 bandNameList = spectrumAdapter.getBandNames();
090 bandNameMap = spectrumAdapter.getBandNameMap();
091 }
092 try {
093 setInitialWavenumber(getWavenumberFromChannelIndex(0));
094 }
095 catch (Exception e) {
096 e.printStackTrace();
097 System.out.println("could not initialize initial wavenumber");
098 }
099 }
100
101 if (swathAdapter != null) {
102 this.swathSelect = swathAdapter.getDefaultSubset();
103 if (spectrumAdapter != null) {
104 spectrumAdapter.setRangeProcessor(swathAdapter.getRangeProcessor());
105 }
106 }
107
108 this.sensorName = sensorName;
109 this.platformName = platformName;
110 }
111
112 public MultiSpectralData(SwathAdapter swathAdapter, SpectrumAdapter spectrumAdapter,
113 String sensorName, String platformName) {
114 this(swathAdapter, spectrumAdapter, "Radiance", "BrightnessTemp", sensorName, platformName);
115 }
116
117 public MultiSpectralData(SwathAdapter swathAdapter, SpectrumAdapter spectrumAdapter) {
118 this(swathAdapter, spectrumAdapter, null, null);
119 }
120
121 public MultiSpectralData() {
122 this(null, null, null, null);
123 }
124
125 public FlatField getSpectrum(int[] coords)
126 throws Exception, VisADException, RemoteException {
127 if (coords == null) return null;
128 if (spectrumAdapter == null) return null;
129 spectrumSelect.put(SpectrumAdapter.x_dim_name, new double[] {(double)coords[0], (double)coords[0], 1.0});
130 spectrumSelect.put(SpectrumAdapter.y_dim_name, new double[] {(double)coords[1], (double)coords[1], 1.0});
131
132 FlatField spectrum = spectrumAdapter.getData(spectrumSelect);
133 return convertSpectrum(spectrum, paramName);
134 }
135
136 public FlatField getSpectrum(RealTuple location)
137 throws Exception, VisADException, RemoteException {
138 if (spectrumAdapter == null) return null;
139 int[] coords = getSwathCoordinates(location, cs);
140 if (coords == null) return null;
141 spectrumSelect.put(SpectrumAdapter.x_dim_name, new double[] {(double)coords[0], (double)coords[0], 1.0});
142 spectrumSelect.put(SpectrumAdapter.y_dim_name, new double[] {(double)coords[1], (double)coords[1], 1.0});
143
144 FlatField spectrum = spectrumAdapter.getData(spectrumSelect);
145 return convertSpectrum(spectrum, paramName);
146 }
147
148 public FlatField getImage(HashMap subset)
149 throws Exception, VisADException, RemoteException {
150 FlatField image = swathAdapter.getData(subset);
151 cs = ((RealTupleType) ((FunctionType)image.getType()).getDomain()).getCoordinateSystem();
152
153 int channelIndex = (int) ((double[])subset.get(SpectrumAdapter.channelIndex_name))[0];
154 float channel = spectrumAdapter.getWavenumberFromChannelIndex(channelIndex);
155
156 return convertImage(image, channel, paramName);
157 }
158
159 public FlatField getImage(float channel, HashMap subset)
160 throws Exception, VisADException, RemoteException {
161 if (spectrumAdapter == null) return getImage(subset);
162 int channelIndex = spectrumAdapter.getChannelIndexFromWavenumber(channel);
163 subset.put(SpectrumAdapter.channelIndex_name, new double[] {(double)channelIndex, (double)channelIndex, 1.0});
164 FlatField image = swathAdapter.getData(subset);
165 cs = ((RealTupleType) ((FunctionType)image.getType()).getDomain()).getCoordinateSystem();
166
167 return convertImage(image, channel, paramName);
168 }
169
170 public FlatField getData(Object subset) throws Exception {
171 return getImage((HashMap)subset);
172 }
173
174 public Set makeDomain(Object subset) throws Exception {
175 throw new Exception("makeDomain unimplented");
176 }
177
178
179 FlatField convertImage(FlatField image, float channel, String param)
180 throws Exception {
181 FlatField new_image = null;
182 FunctionType f_type = (FunctionType)image.getType();
183 if (param.equals("BrightnessTemp")) { //- convert radiance to BrightnessTemp
184 FunctionType new_type = new FunctionType(f_type.getDomain(), RealType.getRealType("BrightnessTemp"));
185 new_image = new FlatField(new_type, image.getDomainSet());
186 float[][] values = image.getFloats(false);
187 float[] bt_values = values[0];
188 if (inputParamName == "Radiance") {
189 bt_values = radianceToBrightnessTemp(values[0], channel, platformName, sensorName);
190 }
191 new_image.setSamples(new float[][] {bt_values}, false);
192 }
193 else if (param.equals("Reflectance")) {
194 FunctionType new_type = new FunctionType(f_type.getDomain(), RealType.getRealType("Reflectance"));
195 new_image = new FlatField(new_type, image.getDomainSet());
196 new_image.setSamples(image.getFloats(false), false);
197 }
198 else {
199 new_image = image;
200 }
201 return new_image;
202 }
203
204
205 FlatField convertSpectrum(FlatField spectrum, String param) throws Exception {
206 FlatField new_spectrum = null;
207 FunctionType f_type = (FunctionType) spectrum.getType();
208
209 if (param.equals("BrightnessTemp")) {
210 FunctionType new_type = new FunctionType(f_type.getDomain(), RealType.getRealType("BrightnessTemp"));
211 float[][] channels = ((SampledSet)spectrum.getDomainSet()).getSamples(false);
212 float[][] values = spectrum.getFloats(false);
213 float[] bt_values = values[0];
214 if (inputParamName == "Radiance") {
215 bt_values = radianceToBrightnessTempSpectrum(values[0], channels[0], platformName, sensorName);
216 }
217 new_spectrum = new FlatField(new_type, spectrum.getDomainSet());
218 new_spectrum.setSamples(new float[][] {bt_values}, true);
219 }
220 else if (param.equals("Reflectance")) {
221 FunctionType new_type = new FunctionType(f_type.getDomain(), RealType.getRealType("Reflectance"));
222 new_spectrum = new FlatField(new_type, spectrum.getDomainSet());
223 new_spectrum.setSamples(spectrum.getFloats(false), false);
224 }
225 else {
226 new_spectrum = spectrum;
227 }
228 return new_spectrum;
229 }
230
231 protected void setDataRange(float[] range) {
232 dataRange = range;
233 }
234
235 public float[] getDataRange() {
236 return dataRange;
237 }
238
239 public String getParameter() {
240 return paramName;
241 }
242
243 public String getName() {
244 return name;
245 }
246
247 public CoordinateSystem getCoordinateSystem() {
248 return cs;
249 }
250
251 public void setCoordinateSystem(CoordinateSystem cs) {
252 this.cs = cs;
253 }
254
255 public boolean hasBandNames() {
256 return hasBandNames;
257 }
258
259 public ArrayList<String> getBandNames() {
260 return bandNameList;
261 }
262
263 public HashMap<String, Float> getBandNameMap() {
264 return bandNameMap;
265 }
266
267 public String getBandNameFromWaveNumber(float channel) {
268 String bandName = null;
269 Iterator iter = bandNameMap.keySet().iterator();
270 while (iter.hasNext()) {
271 String key = (String) iter.next();
272 float mapVal = ((Float)bandNameMap.get(key)).floatValue();
273 if (channel == mapVal) {
274 bandName = key;
275 break;
276 }
277 }
278 return bandName;
279 }
280
281 public void setInitialWavenumber(float val) {
282 init_wavenumber = val;
283 if (hasBandNames) {
284 init_bandName = getBandNameFromWaveNumber(init_wavenumber);
285 }
286 }
287
288 public int[] getSwathCoordinates(RealTuple location, CoordinateSystem cs)
289 throws VisADException, RemoteException {
290 if (location == null) return null;
291 if (cs == null) return null;
292 Real[] comps = location.getRealComponents();
293 //- trusted: latitude:0, longitude:1
294 float lon = (float) comps[1].getValue();
295 float lat = (float) comps[0].getValue();
296 if (lon < -180) lon += 360f;
297 if (lon > 180) lon -= 360f;
298 float[][] xy = cs.fromReference(new float[][] {{lon}, {lat}});
299 if ((Float.isNaN(xy[0][0])) || Float.isNaN(xy[1][0])) return null;
300 Set domain = swathAdapter.getSwathDomain();
301 int[] idx = domain.valueToIndex(xy);
302 xy = domain.indexToValue(idx);
303 int[] coords = new int[2];
304 coords[0] = (int) xy[0][0];
305 coords[1] = (int) xy[1][0];
306 if ((coords[0] < 0)||(coords[1] < 0)) return null;
307 return coords;
308 }
309
310 public RealTuple getEarthCoordinates(float[] xy)
311 throws VisADException, RemoteException {
312 float[][] tup = cs.toReference(new float[][] {{xy[0]}, {xy[1]}});
313 return new RealTuple(RealTupleType.SpatialEarth2DTuple, new double[] {(double)tup[0][0], (double)tup[1][0]});
314 }
315
316 public int getChannelIndexFromWavenumber(float channel) throws Exception {
317 return spectrumAdapter.getChannelIndexFromWavenumber(channel);
318 }
319
320 public float getWavenumberFromChannelIndex(int index) throws Exception {
321 return spectrumAdapter.getWavenumberFromChannelIndex(index);
322 }
323
324 public Rectangle2D getLonLatBoundingBox(CoordinateSystem cs) {
325 return null;
326 }
327
328 public Rectangle2D getLonLatBoundingBox(HashMap subset)
329 throws Exception {
330 Set domainSet = swathAdapter.makeDomain(subset);
331 return getLonLatBoundingBox(domainSet);
332 }
333
334 public static Rectangle2D getLonLatBoundingBox(FlatField field) {
335 Set domainSet = field.getDomainSet();
336 return getLonLatBoundingBox(domainSet);
337 }
338
339 public static float[][] getLonLatBoundingCorners(Set domainSet) {
340 CoordinateSystem cs =
341 ((SetType)domainSet.getType()).getDomain().getCoordinateSystem();
342
343 float start0, stop0, start1, stop1;
344 int len0, len1;
345 float minLon = Float.MAX_VALUE;
346 float minLat = Float.MAX_VALUE;
347 float maxLon = -Float.MAX_VALUE;
348 float maxLat = -Float.MAX_VALUE;
349
350 float[][] corners = null;
351
352 if (domainSet instanceof Linear2DSet) {
353 Linear1DSet lset = ((Linear2DSet)domainSet).getLinear1DComponent(0);
354 start0 = (float) lset.getFirst();
355 stop0 = (float) lset.getLast();
356 len0 = lset.getLengthX();
357 lset = ((Linear2DSet)domainSet).getLinear1DComponent(1);
358 start1 = (float) lset.getFirst();
359 stop1 = (float) lset.getLast();
360 len1 = lset.getLengthX();
361
362 float x, y, del_x, del_y;
363 float lonA = Float.NaN;
364 float lonB = Float.NaN;
365 float lonC = Float.NaN;
366 float lonD = Float.NaN;
367 float latA = Float.NaN;
368 float latB = Float.NaN;
369 float latC = Float.NaN;
370 float latD = Float.NaN;
371
372 int nXpts = len0/1;
373 int nYpts = len1/1;
374
375 del_x = (stop0 - start0)/nXpts;
376 del_y = (stop1 - start1)/nYpts;
377 x = start0;
378 y = start1;
379 try {
380 for (int j=0; j<nYpts; j++) {
381 y = start1+j*del_y;
382 for (int i=0; i<nXpts; i++) {
383 x = start0 + i*del_x;
384 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
385 float lon = lonlat[0][0];
386 float lat = lonlat[1][0];
387 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
388 lonA = lon;
389 latA = lat;
390 break;
391 }
392 }
393 for (int i=0; i<nXpts; i++) {
394 x = stop0 - i*del_x;
395 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
396 float lon = lonlat[0][0];
397 float lat = lonlat[1][0];
398 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
399 lonB = lon;
400 latB = lat;
401 break;
402 }
403 }
404 if (!Float.isNaN(lonA) && !Float.isNaN(lonB)) {
405 break;
406 }
407 }
408
409 for (int j=0; j<nYpts; j++) {
410 y = stop1-j*del_y;
411 for (int i=0; i<nXpts; i++) {
412 x = start0 + i*del_x;
413 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
414 float lon = lonlat[0][0];
415 float lat = lonlat[1][0];
416 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
417 lonC = lon;
418 latC = lat;
419 break;
420 }
421 }
422 for (int i=0; i<nXpts; i++) {
423 x = stop0 - i*del_x;
424 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
425 float lon = lonlat[0][0];
426 float lat = lonlat[1][0];
427 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
428 lonD = lon;
429 latD = lat;
430 break;
431 }
432 }
433 if (!Float.isNaN(lonC) && !Float.isNaN(lonD)) {
434 break;
435 }
436 }
437 corners = new float[][] {{lonA,lonB,lonC,lonD},{latA,latB,latC,latD}};
438 for (int k=0; k<corners[0].length; k++) {
439 float lon = corners[0][k];
440 float lat = corners[1][k];
441 /**
442 if (lon < minLon) minLon = lon;
443 if (lat < minLat) minLat = lat;
444 if (lon > maxLon) maxLon = lon;
445 if (lat > maxLat) maxLat = lat;
446 */
447 }
448 } catch (Exception e) {
449 }
450 }
451 else if (domainSet instanceof Gridded2DSet) {
452 int[] lens = ((Gridded2DSet)domainSet).getLengths();
453 start0 = 0f;
454 start1 = 0f;
455 stop0 = (float) lens[0];
456 stop1 = (float) lens[1];
457
458 float x, y, del_x, del_y;
459 del_x = (stop0 - start0)/10;
460 del_y = (stop1 - start1)/10;
461 x = start0;
462 y = start1;
463 try {
464 for (int j=0; j<11; j++) {
465 y = start1+j*del_y;
466 for (int i=0; i<11; i++) {
467 x = start0+i*del_x;
468 float[][] lonlat = ((Gridded2DSet)domainSet).gridToValue(new float[][] {{x}, {y}});
469 float lon = lonlat[0][0];
470 float lat = lonlat[1][0];
471 if ((lon > 180 || lon < -180) || (lat > 90 || lat < -90)) continue;
472 if (lon < minLon) minLon = lon;
473 if (lat < minLat) minLat = lat;
474 if (lon > maxLon) maxLon = lon;
475 if (lat > maxLat) maxLat = lat;
476 }
477 }
478 } catch (Exception e) {
479 }
480 }
481
482
483 float del_lon = maxLon - minLon;
484 float del_lat = maxLat - minLat;
485
486 return corners;
487 }
488
489 public static Rectangle2D getLonLatBoundingBox(Set domainSet) {
490 CoordinateSystem cs =
491 ((SetType)domainSet.getType()).getDomain().getCoordinateSystem();
492
493 float start0, stop0, start1, stop1;
494 int len0, len1;
495 float minLon = Float.MAX_VALUE;
496 float minLat = Float.MAX_VALUE;
497 float maxLon = -Float.MAX_VALUE;
498 float maxLat = -Float.MAX_VALUE;
499
500
501 if (domainSet instanceof Linear2DSet) {
502 Linear1DSet lset = ((Linear2DSet)domainSet).getLinear1DComponent(0);
503 start0 = (float) lset.getFirst();
504 stop0 = (float) lset.getLast();
505 len0 = lset.getLengthX();
506 lset = ((Linear2DSet)domainSet).getLinear1DComponent(1);
507 start1 = (float) lset.getFirst();
508 stop1 = (float) lset.getLast();
509 len1 = lset.getLengthX();
510
511 float x, y, del_x, del_y;
512 float lonA = Float.NaN;
513 float lonB = Float.NaN;
514 float lonC = Float.NaN;
515 float lonD = Float.NaN;
516 float latA = Float.NaN;
517 float latB = Float.NaN;
518 float latC = Float.NaN;
519 float latD = Float.NaN;
520
521 int nXpts = len0/8;
522 int nYpts = len1/8;
523
524 del_x = (stop0 - start0)/nXpts;
525 del_y = (stop1 - start1)/nYpts;
526
527 x = start0;
528 y = start1;
529 try {
530 for (int j=0; j<nYpts; j++) {
531 y = start1+j*del_y;
532 for (int i=0; i<nXpts; i++) {
533 x = start0 + i*del_x;
534 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
535 float lon = lonlat[0][0];
536 float lat = lonlat[1][0];
537 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
538 lonA = lon;
539 latA = lat;
540 break;
541 }
542 }
543 for (int i=0; i<nXpts; i++) {
544 x = stop0 - i*del_x;
545 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
546 float lon = lonlat[0][0];
547 float lat = lonlat[1][0];
548 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
549 lonB = lon;
550 latB = lat;
551 break;
552 }
553 }
554 if (!Float.isNaN(lonA) && !Float.isNaN(lonB)) {
555 break;
556 }
557 }
558
559 for (int j=0; j<nYpts; j++) {
560 y = stop1-j*del_y;
561 for (int i=0; i<nXpts; i++) {
562 x = start0 + i*del_x;
563 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
564 float lon = lonlat[0][0];
565 float lat = lonlat[1][0];
566 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
567 lonC = lon;
568 latC = lat;
569 break;
570 }
571 }
572 for (int i=0; i<nXpts; i++) {
573 x = stop0 - i*del_x;
574 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}});
575 float lon = lonlat[0][0];
576 float lat = lonlat[1][0];
577 if (!Float.isNaN(lon) && !Float.isNaN(lat)) {
578 lonD = lon;
579 latD = lat;
580 break;
581 }
582 }
583 if (!Float.isNaN(lonC) && !Float.isNaN(lonD)) {
584 break;
585 }
586 }
587 float[][] corners = {{lonA,lonB,lonC,lonD},{latA,latB,latC,latD}};
588 for (int k=0; k<corners[0].length; k++) {
589 float lon = corners[0][k];
590 float lat = corners[1][k];
591 if (lon < minLon) minLon = lon;
592 if (lat < minLat) minLat = lat;
593 if (lon > maxLon) maxLon = lon;
594 if (lat > maxLat) maxLat = lat;
595 }
596 } catch (Exception e) {
597 }
598 }
599 else if (domainSet instanceof Gridded2DSet) {
600 int[] lens = ((Gridded2DSet)domainSet).getLengths();
601 start0 = 0f;
602 start1 = 0f;
603 stop0 = (float) lens[0];
604 stop1 = (float) lens[1];
605
606 float x, y, del_x, del_y;
607 del_x = (stop0 - start0)/10;
608 del_y = (stop1 - start1)/10;
609 x = start0;
610 y = start1;
611 try {
612 for (int j=0; j<11; j++) {
613 y = start1+j*del_y;
614 for (int i=0; i<11; i++) {
615 x = start0+i*del_x;
616 float[][] lonlat = ((Gridded2DSet)domainSet).gridToValue(new float[][] {{x}, {y}});
617 float lon = lonlat[0][0];
618 float lat = lonlat[1][0];
619 if ((lon > 180 || lon < -180) || (lat > 90 || lat < -90)) continue;
620 if (lon < minLon) minLon = lon;
621 if (lat < minLat) minLat = lat;
622 if (lon > maxLon) maxLon = lon;
623 if (lat > maxLat) maxLat = lat;
624 }
625 }
626 } catch (Exception e) {
627 }
628 }
629
630
631 float del_lon = maxLon - minLon;
632 float del_lat = maxLat - minLat;
633
634 return new Rectangle2D.Float(minLon, minLat, del_lon, del_lat);
635 }
636
637 public float[] radianceToBrightnessTemp(float[] values, float channelValue) {
638 float c1=1.191066E-5f; //- mW/m2/ster/cm^-4
639 float c2=1.438833f; //- K*cm
640 float nu = channelValue; //- nu: wavenumber
641 float B, K, BT;
642
643 int n_values = values.length;
644 float[] new_values = new float[n_values];
645 for (int i=0; i<n_values;i++) {
646 B = values[i];
647 K = (c1*nu*nu*nu)/B;
648 if (K == 0.0) {
649 BT = B;
650 }
651 else {
652 BT = c2*nu/((float) (Math.log((double)((c1*nu*nu*nu)/B)+1.0f)) );
653 }
654 if (BT < 0.01) BT = Float.NaN;
655 new_values[i] = BT;
656 }
657 return new_values;
658 }
659
660 public float[] radianceToBrightnessTemp(float[] values, float channelValue, String platformName, String sensorName)
661 throws Exception {
662 float[] new_values = null;
663
664 if (sensorName == null) {
665 new_values = radianceToBrightnessTemp(values, channelValue);
666 }
667 else if (sensorName == "MODIS") {
668 int channelIndex = spectrumAdapter.getChannelIndexFromWavenumber(channelValue);
669 int band_number = MODIS_L1B_Utility.emissive_indexToBandNumber(channelIndex);
670 new_values = MODIS_L1B_Utility.modis_radiance_to_brightnessTemp(platformName, band_number, values);
671 }
672 return new_values;
673 }
674
675 public float[] radianceToBrightnessTempSpectrum(float[] values, float[] channelValues) {
676 //- Converts radiances [mW/ster/m2/cm^-1] to BT [K]
677 //- Input: nu array of wavenmbers [cm^-1]
678 //- B radiances [mW/ster/m2/cm^-1]
679 //- Output: bt brightness temperature in [K]
680 //- Paolo Antonelli
681 //- Wed Feb 25 16:43:05 CST 1998
682
683 float c1=1.191066E-5f; //- mW/m2/ster/cm^-4
684 float c2=1.438833f; //- K*cm
685
686 float nu; //- wavenumber
687 float B, BT;
688
689 int n_values = values.length;
690 float[] new_values = new float[n_values];
691 for (int i=0; i<n_values; i++) {
692 nu = channelValues[i];
693 B = values[i];
694 BT = c2*nu/((float) (Math.log(((c1*nu*nu*nu)/B)+1.0f)) );
695 new_values[i] = BT;
696 }
697 return new_values;
698 }
699
700
701 public float[] radianceToBrightnessTempSpectrum(float[] values, float[] channelValues,
702 String platformName, String sensorName)
703 throws Exception
704 {
705 float[] new_values = null;
706
707 if (sensorName == null) {
708 new_values = radianceToBrightnessTempSpectrum(values, channelValues);
709 }
710 else if (sensorName == "MODIS") {
711 new_values = new float[values.length];
712 for (int k=0; k<new_values.length; k++) {
713 int channelIndex = spectrumAdapter.getChannelIndexFromWavenumber(channelValues[k]);
714 int band_number = MODIS_L1B_Utility.emissive_indexToBandNumber(channelIndex);
715 float[] tmp = new float[1];
716 tmp[0] = values[k];
717 new_values[k] = (MODIS_L1B_Utility.modis_radiance_to_brightnessTemp(platformName, band_number, tmp))[0];
718 }
719 }
720
721 return new_values;
722 }
723
724 public HashMap getDefaultSubset() {
725 HashMap subset = swathAdapter.getDefaultSubset();
726 double chanIdx=0;
727
728 try {
729 chanIdx = spectrumAdapter.getChannelIndexFromWavenumber(init_wavenumber);
730 }
731 catch (Exception e) {
732 System.out.println("couldn't get chanIdx, using zero");
733 }
734
735 subset.put(SpectrumAdapter.channelIndex_name, new double[] {chanIdx, chanIdx, 1});
736 return subset;
737 }
738
739
740 public SpectrumAdapter getSpectrumAdapter() {
741 return spectrumAdapter;
742 }
743 }