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 }