001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2015 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 java.awt.geom.Rectangle2D; 032import java.rmi.RemoteException; 033import java.util.ArrayList; 034import java.util.HashMap; 035import java.util.Iterator; 036 037import visad.CoordinateSystem; 038import visad.FlatField; 039import visad.FunctionType; 040import visad.Gridded2DSet; 041import visad.Linear1DSet; 042import visad.Linear2DSet; 043import visad.Real; 044import visad.RealTuple; 045import visad.RealTupleType; 046import visad.RealType; 047import visad.SampledSet; 048import visad.Set; 049import visad.SetType; 050import visad.VisADException; 051 052public 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 /** 244 * @return the paramName 245 */ 246 public String getParamName() { 247 return paramName; 248 } 249 250 /** 251 * @param paramName the paramName to set 252 */ 253 public void setParamName(String paramName) { 254 this.paramName = paramName; 255 } 256 257 public String getName() { 258 return name; 259 } 260 261 public CoordinateSystem getCoordinateSystem() { 262 return cs; 263 } 264 265 public void setCoordinateSystem(CoordinateSystem cs) { 266 this.cs = cs; 267 } 268 269 public boolean hasBandNames() { 270 return hasBandNames; 271 } 272 273 public ArrayList<String> getBandNames() { 274 return bandNameList; 275 } 276 277 public HashMap<String, Float> getBandNameMap() { 278 return bandNameMap; 279 } 280 281 public String getBandNameFromWaveNumber(float channel) { 282 String bandName = null; 283 Iterator iter = bandNameMap.keySet().iterator(); 284 while (iter.hasNext()) { 285 String key = (String) iter.next(); 286 float mapVal = ((Float)bandNameMap.get(key)).floatValue(); 287 if (channel == mapVal) { 288 bandName = key; 289 break; 290 } 291 } 292 return bandName; 293 } 294 295 public void setInitialWavenumber(float val) { 296 init_wavenumber = val; 297 if (hasBandNames) { 298 init_bandName = getBandNameFromWaveNumber(init_wavenumber); 299 } 300 } 301 302 public int[] getSwathCoordinates(RealTuple location, CoordinateSystem cs) 303 throws VisADException, RemoteException { 304 if (location == null) return null; 305 if (cs == null) return null; 306 Real[] comps = location.getRealComponents(); 307 //- trusted: latitude:0, longitude:1 308 float lon = (float) comps[1].getValue(); 309 float lat = (float) comps[0].getValue(); 310 if (lon < -180) lon += 360f; 311 if (lon > 180) lon -= 360f; 312 float[][] xy = cs.fromReference(new float[][] {{lon}, {lat}}); 313 if ((Float.isNaN(xy[0][0])) || Float.isNaN(xy[1][0])) return null; 314 Set domain = swathAdapter.getSwathDomain(); 315 int[] idx = domain.valueToIndex(xy); 316 xy = domain.indexToValue(idx); 317 int[] coords = new int[2]; 318 coords[0] = (int) xy[0][0]; 319 coords[1] = (int) xy[1][0]; 320 if ((coords[0] < 0)||(coords[1] < 0)) return null; 321 return coords; 322 } 323 324 public RealTuple getEarthCoordinates(float[] xy) 325 throws VisADException, RemoteException { 326 float[][] tup = cs.toReference(new float[][] {{xy[0]}, {xy[1]}}); 327 return new RealTuple(RealTupleType.SpatialEarth2DTuple, new double[] {(double)tup[0][0], (double)tup[1][0]}); 328 } 329 330 public int getChannelIndexFromWavenumber(float channel) throws Exception { 331 return spectrumAdapter.getChannelIndexFromWavenumber(channel); 332 } 333 334 public float getWavenumberFromChannelIndex(int index) throws Exception { 335 return spectrumAdapter.getWavenumberFromChannelIndex(index); 336 } 337 338 public Rectangle2D getLonLatBoundingBox(CoordinateSystem cs) { 339 return null; 340 } 341 342 public Rectangle2D getLonLatBoundingBox(HashMap subset) 343 throws Exception { 344 Set domainSet = swathAdapter.makeDomain(subset); 345 return getLonLatBoundingBox(domainSet); 346 } 347 348 public static Rectangle2D getLonLatBoundingBox(FlatField field) { 349 Set domainSet = field.getDomainSet(); 350 return getLonLatBoundingBox(domainSet); 351 } 352 353 public static float[][] getLonLatBoundingCorners(Set domainSet) { 354 CoordinateSystem cs = 355 ((SetType)domainSet.getType()).getDomain().getCoordinateSystem(); 356 357 float start0, stop0, start1, stop1; 358 int len0, len1; 359 float minLon = Float.MAX_VALUE; 360 float minLat = Float.MAX_VALUE; 361 float maxLon = -Float.MAX_VALUE; 362 float maxLat = -Float.MAX_VALUE; 363 364 float[][] corners = null; 365 366 if (domainSet instanceof Linear2DSet) { 367 Linear1DSet lset = ((Linear2DSet)domainSet).getLinear1DComponent(0); 368 start0 = (float) lset.getFirst(); 369 stop0 = (float) lset.getLast(); 370 len0 = lset.getLengthX(); 371 lset = ((Linear2DSet)domainSet).getLinear1DComponent(1); 372 start1 = (float) lset.getFirst(); 373 stop1 = (float) lset.getLast(); 374 len1 = lset.getLengthX(); 375 376 float x, y, del_x, del_y; 377 float lonA = Float.NaN; 378 float lonB = Float.NaN; 379 float lonC = Float.NaN; 380 float lonD = Float.NaN; 381 float latA = Float.NaN; 382 float latB = Float.NaN; 383 float latC = Float.NaN; 384 float latD = Float.NaN; 385 386 int nXpts = len0/1; 387 int nYpts = len1/1; 388 389 del_x = (stop0 - start0)/nXpts; 390 del_y = (stop1 - start1)/nYpts; 391 x = start0; 392 y = start1; 393 try { 394 for (int j=0; j<nYpts; j++) { 395 y = start1+j*del_y; 396 for (int i=0; i<nXpts; i++) { 397 x = start0 + i*del_x; 398 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 399 float lon = lonlat[0][0]; 400 float lat = lonlat[1][0]; 401 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 402 lonA = lon; 403 latA = lat; 404 break; 405 } 406 } 407 for (int i=0; i<nXpts; i++) { 408 x = stop0 - i*del_x; 409 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 410 float lon = lonlat[0][0]; 411 float lat = lonlat[1][0]; 412 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 413 lonB = lon; 414 latB = lat; 415 break; 416 } 417 } 418 if (!Float.isNaN(lonA) && !Float.isNaN(lonB)) { 419 break; 420 } 421 } 422 423 for (int j=0; j<nYpts; j++) { 424 y = stop1-j*del_y; 425 for (int i=0; i<nXpts; i++) { 426 x = start0 + i*del_x; 427 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 428 float lon = lonlat[0][0]; 429 float lat = lonlat[1][0]; 430 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 431 lonC = lon; 432 latC = lat; 433 break; 434 } 435 } 436 for (int i=0; i<nXpts; i++) { 437 x = stop0 - i*del_x; 438 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 439 float lon = lonlat[0][0]; 440 float lat = lonlat[1][0]; 441 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 442 lonD = lon; 443 latD = lat; 444 break; 445 } 446 } 447 if (!Float.isNaN(lonC) && !Float.isNaN(lonD)) { 448 break; 449 } 450 } 451 // TJJ - should these be validated? See history, lost some dead code here 452 corners = new float[][] {{lonA,lonB,lonC,lonD},{latA,latB,latC,latD}}; 453 } catch (Exception e) { 454 } 455 } 456 else if (domainSet instanceof Gridded2DSet) { 457 int[] lens = ((Gridded2DSet)domainSet).getLengths(); 458 start0 = 0f; 459 start1 = 0f; 460 stop0 = (float) lens[0]; 461 stop1 = (float) lens[1]; 462 463 float x, y, del_x, del_y; 464 del_x = (stop0 - start0)/10; 465 del_y = (stop1 - start1)/10; 466 x = start0; 467 y = start1; 468 try { 469 for (int j=0; j<11; j++) { 470 y = start1+j*del_y; 471 for (int i=0; i<11; i++) { 472 x = start0+i*del_x; 473 float[][] lonlat = ((Gridded2DSet)domainSet).gridToValue(new float[][] {{x}, {y}}); 474 float lon = lonlat[0][0]; 475 float lat = lonlat[1][0]; 476 if ((lon > 180 || lon < -180) || (lat > 90 || lat < -90)) continue; 477 if (lon < minLon) minLon = lon; 478 if (lat < minLat) minLat = lat; 479 if (lon > maxLon) maxLon = lon; 480 if (lat > maxLat) maxLat = lat; 481 } 482 } 483 } catch (Exception e) { 484 } 485 } 486 487 return corners; 488 } 489 490 public static Rectangle2D getLonLatBoundingBox(Set domainSet) { 491 CoordinateSystem cs = 492 ((SetType)domainSet.getType()).getDomain().getCoordinateSystem(); 493 494 float start0, stop0, start1, stop1; 495 int len0, len1; 496 float minLon = Float.MAX_VALUE; 497 float minLat = Float.MAX_VALUE; 498 float maxLon = -Float.MAX_VALUE; 499 float maxLat = -Float.MAX_VALUE; 500 501 502 if (domainSet instanceof Linear2DSet) { 503 Linear1DSet lset = ((Linear2DSet)domainSet).getLinear1DComponent(0); 504 start0 = (float) lset.getFirst(); 505 stop0 = (float) lset.getLast(); 506 len0 = lset.getLengthX(); 507 lset = ((Linear2DSet)domainSet).getLinear1DComponent(1); 508 start1 = (float) lset.getFirst(); 509 stop1 = (float) lset.getLast(); 510 len1 = lset.getLengthX(); 511 512 float x, y, del_x, del_y; 513 float lonA = Float.NaN; 514 float lonB = Float.NaN; 515 float lonC = Float.NaN; 516 float lonD = Float.NaN; 517 float latA = Float.NaN; 518 float latB = Float.NaN; 519 float latC = Float.NaN; 520 float latD = Float.NaN; 521 522 int nXpts = len0/8; 523 int nYpts = len1/8; 524 525 del_x = (stop0 - start0)/nXpts; 526 del_y = (stop1 - start1)/nYpts; 527 528 x = start0; 529 y = start1; 530 try { 531 for (int j=0; j<nYpts; j++) { 532 y = start1+j*del_y; 533 for (int i=0; i<nXpts; i++) { 534 x = start0 + i*del_x; 535 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 536 float lon = lonlat[0][0]; 537 float lat = lonlat[1][0]; 538 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 539 lonA = lon; 540 latA = lat; 541 break; 542 } 543 } 544 for (int i=0; i<nXpts; i++) { 545 x = stop0 - i*del_x; 546 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 547 float lon = lonlat[0][0]; 548 float lat = lonlat[1][0]; 549 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 550 lonB = lon; 551 latB = lat; 552 break; 553 } 554 } 555 if (!Float.isNaN(lonA) && !Float.isNaN(lonB)) { 556 break; 557 } 558 } 559 560 for (int j=0; j<nYpts; j++) { 561 y = stop1-j*del_y; 562 for (int i=0; i<nXpts; i++) { 563 x = start0 + i*del_x; 564 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 565 float lon = lonlat[0][0]; 566 float lat = lonlat[1][0]; 567 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 568 lonC = lon; 569 latC = lat; 570 break; 571 } 572 } 573 for (int i=0; i<nXpts; i++) { 574 x = stop0 - i*del_x; 575 float[][] lonlat = cs.toReference(new float[][] {{x}, {y}}); 576 float lon = lonlat[0][0]; 577 float lat = lonlat[1][0]; 578 if (!Float.isNaN(lon) && !Float.isNaN(lat)) { 579 lonD = lon; 580 latD = lat; 581 break; 582 } 583 } 584 if (!Float.isNaN(lonC) && !Float.isNaN(lonD)) { 585 break; 586 } 587 } 588 float[][] corners = {{lonA,lonB,lonC,lonD},{latA,latB,latC,latD}}; 589 for (int k=0; k<corners[0].length; k++) { 590 float lon = corners[0][k]; 591 float lat = corners[1][k]; 592 if (lon < minLon) minLon = lon; 593 if (lat < minLat) minLat = lat; 594 if (lon > maxLon) maxLon = lon; 595 if (lat > maxLat) maxLat = lat; 596 } 597 } catch (Exception e) { 598 } 599 } 600 else if (domainSet instanceof Gridded2DSet) { 601 int[] lens = ((Gridded2DSet)domainSet).getLengths(); 602 start0 = 0f; 603 start1 = 0f; 604 stop0 = (float) lens[0]; 605 stop1 = (float) lens[1]; 606 607 float x, y, del_x, del_y; 608 del_x = (stop0 - start0)/10; 609 del_y = (stop1 - start1)/10; 610 x = start0; 611 y = start1; 612 try { 613 for (int j=0; j<11; j++) { 614 y = start1+j*del_y; 615 for (int i=0; i<11; i++) { 616 x = start0+i*del_x; 617 float[][] lonlat = ((Gridded2DSet)domainSet).gridToValue(new float[][] {{x}, {y}}); 618 float lon = lonlat[0][0]; 619 float lat = lonlat[1][0]; 620 if ((lon > 180 || lon < -180) || (lat > 90 || lat < -90)) continue; 621 if (lon < minLon) minLon = lon; 622 if (lat < minLat) minLat = lat; 623 if (lon > maxLon) maxLon = lon; 624 if (lat > maxLat) maxLat = lat; 625 } 626 } 627 } catch (Exception e) { 628 } 629 } 630 631 632 float del_lon = maxLon - minLon; 633 float del_lat = maxLat - minLat; 634 635 return new Rectangle2D.Float(minLon, minLat, del_lon, del_lat); 636 } 637 638 public float[] radianceToBrightnessTemp(float[] values, float channelValue) { 639 float c1=1.191066E-5f; //- mW/m2/ster/cm^-4 640 float c2=1.438833f; //- K*cm 641 float nu = channelValue; //- nu: wavenumber 642 float B, K, BT; 643 644 int n_values = values.length; 645 float[] new_values = new float[n_values]; 646 for (int i=0; i<n_values;i++) { 647 B = values[i]; 648 K = (c1*nu*nu*nu)/B; 649 if (K == 0.0) { 650 BT = B; 651 } 652 else { 653 BT = c2*nu/((float) (Math.log((double)((c1*nu*nu*nu)/B)+1.0f)) ); 654 } 655 if (BT < 0.01) BT = Float.NaN; 656 new_values[i] = BT; 657 } 658 return new_values; 659 } 660 661 public float[] radianceToBrightnessTemp(float[] values, float channelValue, String platformName, String sensorName) 662 throws Exception { 663 float[] new_values = null; 664 665 if (sensorName == null) { 666 new_values = radianceToBrightnessTemp(values, channelValue); 667 } 668 else if (sensorName == "MODIS") { 669 int channelIndex = spectrumAdapter.getChannelIndexFromWavenumber(channelValue); 670 int band_number = MODIS_L1B_Utility.emissive_indexToBandNumber(channelIndex); 671 new_values = MODIS_L1B_Utility.modis_radiance_to_brightnessTemp(platformName, band_number, values); 672 } 673 return new_values; 674 } 675 676 public float[] radianceToBrightnessTempSpectrum(float[] values, float[] channelValues) { 677 //- Converts radiances [mW/ster/m2/cm^-1] to BT [K] 678 //- Input: nu array of wavenmbers [cm^-1] 679 //- B radiances [mW/ster/m2/cm^-1] 680 //- Output: bt brightness temperature in [K] 681 //- Paolo Antonelli 682 //- Wed Feb 25 16:43:05 CST 1998 683 684 float c1=1.191066E-5f; //- mW/m2/ster/cm^-4 685 float c2=1.438833f; //- K*cm 686 687 float nu; //- wavenumber 688 float B, BT; 689 690 int n_values = values.length; 691 float[] new_values = new float[n_values]; 692 for (int i=0; i<n_values; i++) { 693 nu = channelValues[i]; 694 B = values[i]; 695 BT = c2*nu/((float) (Math.log(((c1*nu*nu*nu)/B)+1.0f)) ); 696 new_values[i] = BT; 697 } 698 return new_values; 699 } 700 701 702 public float[] radianceToBrightnessTempSpectrum(float[] values, float[] channelValues, 703 String platformName, String sensorName) 704 throws Exception 705 { 706 float[] new_values = null; 707 708 if (sensorName == null) { 709 new_values = radianceToBrightnessTempSpectrum(values, channelValues); 710 } 711 else if (sensorName == "MODIS") { 712 new_values = new float[values.length]; 713 for (int k=0; k<new_values.length; k++) { 714 int channelIndex = spectrumAdapter.getChannelIndexFromWavenumber(channelValues[k]); 715 int band_number = MODIS_L1B_Utility.emissive_indexToBandNumber(channelIndex); 716 float[] tmp = new float[1]; 717 tmp[0] = values[k]; 718 new_values[k] = (MODIS_L1B_Utility.modis_radiance_to_brightnessTemp(platformName, band_number, tmp))[0]; 719 } 720 } 721 722 return new_values; 723 } 724 725 public HashMap getDefaultSubset() { 726 HashMap subset = swathAdapter.getDefaultSubset(); 727 double chanIdx=0; 728 729 try { 730 chanIdx = spectrumAdapter.getChannelIndexFromWavenumber(init_wavenumber); 731 } 732 catch (Exception e) { 733 System.out.println("couldn't get chanIdx, using zero"); 734 } 735 736 subset.put(SpectrumAdapter.channelIndex_name, new double[] {chanIdx, chanIdx, 1}); 737 return subset; 738 } 739 740 741 public SpectrumAdapter getSpectrumAdapter() { 742 return spectrumAdapter; 743 } 744}