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 */
028
029package edu.wisc.ssec.mcidasv.data.hydra;
030
031public class IASI_L1C_Utility {
032
033   public static int[][] ifov_order = new int[][] {new int[] {1,1}, new int[] {0,0}, new int[] {0,1}, new int[] {1,0}};
034   public static int[][] ifov_order2 = new int[][] {new int[] {0,1}, new int[] {1,1}, new int[] {1,0}, new int[] {0,0}};
035   public static int IDefScaleSondNbScale = 5;
036   public static float IDefNsfirst1b      = 2581f;
037   public static float IDefSpectDWn1b     = 25f;  // m-1
038
039   public static float[] IDefScaleSondNsfirst = new float[] { 2581f,
040                                                       5921f,
041                                                       9009f,
042                                                       9541f,
043                                                      10721f};
044                                                                                                                                                        
045   public static float[] IDefScaleSondNslast = new float[] { 5920f,
046                                                       9008f,
047                                                       9540f,
048                                                      10720f,
049                                                      11041f};
050                                                                                                                                                        
051   public static float[] IDefSondScaleFactor = new float[] { 7f, 8f, 9f, 8f, 9f};
052                                                                                                                                                        
053                                                                                                                                                        
054   public static float[] getIASILevel1CSpectralDomain(int num_spectra, float IDefSpectDWn1b, float IDefNsfirst1b, float[] spectrum)
055   {
056     if (spectrum == null) spectrum = new float[num_spectra];
057                                                                                                                                                        
058     for (int k=0; k<num_spectra; k++) {
059       spectrum[k] = IDefSpectDWn1b*(IDefNsfirst1b+k-1);
060     }
061     return spectrum;
062   }
063                                                                                                                                                        
064   public static float[] getIASILevel1CSpectralDomain(int num_spectra, float[] spectrum)
065   {
066     if (spectrum == null) spectrum = new float[num_spectra];
067
068     for (int k=0; k<num_spectra; k++) {
069       spectrum[k] = IDefSpectDWn1b*(IDefNsfirst1b+k-1);
070     }
071     return spectrum;
072   }
073
074   public static float[] getDecodedIASISpectra(short[] codedSpectra, int IDefScaleSondNbScale, float[] IDefSondScaleFactor, float[] IDefScaleSondNsfirst, float[] IDefScaleSondNslast, float IDefNsfirst1b, float[] decodedSpectra) {
075     int num_spectra = codedSpectra.length;
076     if (decodedSpectra == null) decodedSpectra = new float[num_spectra];
077
078     for (int numScale=0; numScale<IDefScaleSondNbScale-1; numScale++) {
079       float scale_factor = IDefSondScaleFactor[numScale];
080       for (int chanNb = (int)IDefScaleSondNsfirst[numScale]; chanNb<(int)IDefScaleSondNslast[numScale]+1; chanNb++) {
081         int w = chanNb - (int)IDefNsfirst1b;
082         decodedSpectra[w] = 1.0E5f*codedSpectra[w]*((float)Math.pow(10.0, (double)-1*scale_factor));
083       }
084     }
085     return decodedSpectra;
086   }
087                                                                                                                                                        
088   public static float[] getDecodedIASISpectra(short[] codedSpectra, float[] decodedSpectra) {
089     int num_spectra = codedSpectra.length;
090     if (decodedSpectra == null) decodedSpectra = new float[num_spectra];
091
092     for (int numScale=0; numScale<IDefScaleSondNbScale; numScale++) {
093       float scale_factor = IDefSondScaleFactor[numScale];
094       for (int chanNb = (int)IDefScaleSondNsfirst[numScale]; chanNb<(int)IDefScaleSondNslast[numScale]+1; chanNb++) {
095         int w = chanNb - (int)IDefNsfirst1b;
096         decodedSpectra[w] = 1.0E5f*codedSpectra[w]*((float)Math.pow(10.0, (double)-1*scale_factor));
097         //-if ((visad.util.Util.isApproximatelyEqual(decodedSpectra[w], 0.0, 0.001))) decodedSpectra[w] += 0.005;
098       }
099     }
100     return decodedSpectra;
101   }
102
103   public static float[] getDecodedIASIImage(short[] image, float[] decodedImage, int channelIndex) {
104     if (decodedImage == null) decodedImage = new float[image.length];
105
106     int scale_idx = -1;
107     channelIndex += IDefNsfirst1b;
108     for (int i=0; i<IDefScaleSondNbScale; i++) { 
109        if ((channelIndex >= IDefScaleSondNsfirst[i]) && (channelIndex <= IDefScaleSondNslast[i])) {
110          scale_idx = i;
111        }
112     }
113     
114     float scale_factor = IDefSondScaleFactor[scale_idx];
115
116     for (int k=0; k<decodedImage.length; k++) {
117       decodedImage[k] = 1.0E5f*image[k]*((float)Math.pow(10.0, (double)-1*scale_factor));
118     }
119
120     return decodedImage;
121   }
122
123   public static float[] psuedoScanReorder(float[] values, int numElems, int numLines) {
124      float[] new_values = new float[values.length];
125
126      for (int j=0; j<numLines/2; j++) { //- loop over EFOVs
127        for (int i=0; i<numElems/2; i++) {
128          int i2 = i*2;
129          int j2 = j*2;
130          for (int jj=0; jj<2; jj++) {  //- loop over IFOVs
131            for (int ii=0; ii<2; ii++) {
132              int k = jj*2 + ii;
133              int idx_ma = (j2+ifov_order[k][0])*numElems + (i2+ifov_order[k][1]); //- idx_ma: mis-aligned
134              int idx_a = (j2+jj)*numElems + i2+ii;  // idx_a: aligned
135              new_values[idx_a] = values[idx_ma];
136            }
137          }
138        }
139      }
140      return new_values;
141   }
142
143   public static float[] psuedoScanReorder2(float[] values, int numElems, int numLines) {
144     float[] new_values = new float[values.length];
145      for (int j=0; j<numLines/2; j++) { //- loop over EFOVs
146        for (int i=0; i<numElems/2; i++) {
147          int i2 = i*2;
148          int j2 = j*2;
149          for (int jj=0; jj<2; jj++) {  //- loop over IFOVs
150            for (int ii=0; ii<2; ii++) {
151              int k = jj*2 + ii;
152              int idx_ma = j*(numElems*2) + i*4 + k;
153              int idx_a = (j2+ifov_order2[k][0])*numElems + i2+ifov_order2[k][1];  // idx_a: aligned
154              new_values[idx_a] = values[idx_ma];
155            }
156          }
157        }
158      }
159      return new_values;
160   }
161}