001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
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 */
028package edu.wisc.ssec.mcidasv.data.hydra;
029
030import visad.Gridded1DSet;
031import visad.Linear1DSet;
032import visad.RealType;
033
034/**
035 * Convert radiance to/from brightness temperature via provided Lookup Tables
036 * 
037 */
038public class LUTtransform {
039   
040   public static final int LINEAR = 0;
041   public static final int GENERAL = 1;
042   
043   int ALGO = LINEAR;
044   
045   float[] radianceLUT;
046   float[] brightnessTempLUT;
047   
048   int numOfLUTvalues;
049   
050   Gridded1DSet radLUTSet;
051   Gridded1DSet btLUTSet;
052   
053   public LUTtransform(float[] radianceLUT, float[] brightnessTempLUT) throws Exception {
054      this(radianceLUT, brightnessTempLUT, GENERAL);
055   }
056   
057   public LUTtransform(float[] radianceLUT, float[] brightnessTempLUT, int algo) throws Exception {
058      this.radianceLUT = radianceLUT;
059      this.brightnessTempLUT = brightnessTempLUT;
060      this.ALGO = algo;
061      
062      numOfLUTvalues = radianceLUT.length;
063      if (numOfLUTvalues != brightnessTempLUT.length) {
064         throw new Exception("radiance and brightnessTemp LUTs must have same length");
065      }
066      
067      switch (ALGO) {
068         case GENERAL:
069            radLUTSet = new Gridded1DSet(RealType.Generic, new float[][] {radianceLUT}, numOfLUTvalues);           
070            btLUTSet = new Gridded1DSet(RealType.Generic, new float[][] {brightnessTempLUT}, numOfLUTvalues);           
071            break;
072         case LINEAR:
073            radLUTSet = new Linear1DSet(radianceLUT[0], radianceLUT[numOfLUTvalues-1], numOfLUTvalues);            
074            btLUTSet = new Linear1DSet(brightnessTempLUT[0], brightnessTempLUT[numOfLUTvalues-1], numOfLUTvalues);            
075            break;
076      }
077   }
078   
079   public float[] radianceToBrightnessTemp(float[] radiances) throws Exception {
080      int numObs = radiances.length;
081      float[] brightnessTemps = new float[numObs];
082      
083      int[] btLUTindexes = radLUTSet.valueToIndex(new float[][] {radiances});
084      
085      for (int k=0; k<numObs; k++) {
086         int idx = btLUTindexes[k];
087         if (idx >= 0) { // Just in case
088            brightnessTemps[k] = brightnessTempLUT[idx];
089         }
090         else {
091            brightnessTemps[k] = Float.NaN;
092         }
093      }
094      
095      return brightnessTemps;
096   }
097   
098   public float[] brightnessTempToRadiance(float[] brightnessTemps) throws Exception {
099      int numObs = brightnessTemps.length;
100      float[] radiances = new float[numObs];
101      
102      int[] radLUTindexes = btLUTSet.valueToIndex(new float[][] {brightnessTemps});
103      for (int k=0; k<numObs; k++) {
104         int idx = radLUTindexes[k];
105         if (idx >= 0) {
106            radiances[k] = radianceLUT[idx];
107         }
108         else {
109            radiances[k] = Float.NaN;
110         }
111      }
112      
113      return radiances;
114   }
115}