GRUVI.sml

  Download

More scripts: Scripts By Jack

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
# ------------------------------------------------------------
# GRUVI.sml
# ------------------------------------------------------------
# SET WARNING LEVEL:
  $warnings 3;
# ------------------------------------------------------------
# DECLARE SEVERAL VARIABLES RELATED TO GRUVI.sml:
  numeric srfiXorg,srfiYorg,slope,bnp,bnpxy,tsrfi,cvi;
  numeric bnpop,bnpi,bnpf,dbnpf;
  numeric srfiXb,srfiYb,srfiXv,srfiYv;
  numeric srfiX,srfiY;
  numeric tsrfiX1,tsrfiY1,tsrfiX2,tsrfiY2,tsrfiX3,tsrfiY3;
  numeric tsrfiX4,tsrfiY4,tsrfiX5,tsrfiY5,tsrfiX6,tsrfiY6;
  numeric nlins,ncols,isnull,i;
  numeric rang,rangdeg,sinrang,cosrang;
  numeric grubif,grubifmin,grubi,grumax,grunull;
  numeric gmean,gstd,gcv1,gcv2,gflag;
  numeric gruvif,gruvi;
  numeric gruvirange,gruvidveg,gfac;
  numeric hnmGB,hnmGF,hnGB,hnGF,nvGB,nvGF,pGB,pGF;
  numeric c1GB,c2GB,c3GB,c1GF,c2GF,c3GF;
  numeric pVI;
  raster SRFIX,SRFIY,GRUVI,GRUBI,GRUFI;
  raster SRFIXT,SRFIYT,GRUVIT;
  string gtype$,rtype$,fore$,back$;
# ------------------------------------------------------------
# DECLARE VARIABLES RELATED TO CONTRAST LOOKUP PROCESS: 
  class CONTRAST smlContrast;
  string clut1$,clut2$,clut3$;
  array numeric v[131072];
  clut1$  = "exp"; clut2$  = "Exponential";
  clut3$  = "Exponential contrast table";
  smlContrast.OutputLowerLimit =   1;
  smlContrast.OutputUpperLimit = 255;
# ------------------------------------------------------------
# DECLARE SEVERAL VARIABLES FOR GENERAL CHARACTER STRINGS:
  string t$,p$,p1$,p2$,p3$,p4$,p5$,p6$,p7$,p8$,p9$;
  string p10$,p11$,p12$,p13$,p14$,p15$,p16$,p17$,p18$,p19$;
  string p20$,p21$;
# ------------------------------------------------------------
# DEFINE PROCEDURE writeTitle:
# PURPOSE: WRITES TITLE & AUTHOR INFO TO CONSOLE WINDOW.
  proc writeTitle(pVIloc) begin
     numeric pVIloc;
     printf("GRUVI.sml:\n");
     printf("         VERSION: November 15, 2005\n");
     if (pVIloc == 1) then begin
        printf("         PURPOSE: PRODUCE GRUVI & GRUBI ");
        printf("RASTERS FROM A PAIR OF\n");
        printf("                  SRFIX & SRFIY RASTERS.\n");
     end
     else begin
        printf("         PURPOSE: PRODUCE GRUFI & GRUBI ");
        printf("RASTERS FROM A PAIR OF\n");
        printf("                  SRFIX & SRFIY RASTERS,\n");
        printf("                  OR FROM A PAIR OF TCX");
        printf(" AND TCY RASTERS (FROM TASCAP.SML).\n");
     end
     printf("     NEW FEATURE: MAKES AUTOMATIC CONTRAST ");
     printf("TABLES.\n");
     printf("         DETAILS: FAQs_by_Jack A & E\n");
     printf("          AUTHOR: Dr. Jack F. Paris\n");
     printf("    CONTACT INFO: [email protected] ");
     printf(" 303-775-1195\n");
     printf("     ALLOWED USE: ONLY NON-COMMERCIAL\n\n");
  end
# ------------------------------------------------------------
# CLEAR CONSOLE WINDOW & REQUEST REPOSITIONING:
  clear();
  p1$ = "CONSOLE-WINDOW ADJUSTMENT\n";
  p2$ = "* REPOSITION the CONSOLE WINDOW.\n";
  p3$ = "* Then, CLICK OK.";
  p$  = p1$ + p2$ + p3$;
  PopupMessage(p$);
# ------------------------------------------------------------
# SELECT USE TYPE:
  p1$ = "GRUVI.sml can be Used in TWO Ways:\n";
  p2$ = "1: Produce GRUVI & GRUBI (Veg. & Bright.)\n";
  p3$ = "2: Produce GRUFI & GRUBI (Foreground & Bright.)\n";
  p4$ = "   DEFAULT: 1 (Veg. & Bright.)\n";
  p5$ = "   WARNING: If Using TC Rasters, SELECT WAY 2!\n";
  p6$ = "WAY SELECTED (1 or 2):";
  p$  = p1$ + p2$ + p3$ + p4$ + p5$ + p6$;
  pVI = PopupNum(p$,1,1,2,0);
# ------------------------------------------------------------
# func GlobalPtile(Rl,ptilel):
  func GlobalPtile(raster Rl, numeric ptilel,hnl,nvl) begin
     local numeric funcval,rl,roffl;
     local numeric nlinsl,ncolsl,linl,coll,il;
     local numeric countl,suml,flagl,cfql;
     roffl = -65535; countl = 0;
     if (hnl == 1) then begin 
        for each Rl begin
           rl = Rl[linl,coll];
           if (rl <> nvl) then countl = countl + 1;
        end
     end
     if (hnl == 0) then begin
        nlinsl = NumLins(Rl); ncolsl = NumCols(Rl);
        countl = nlinsl * ncolsl;
     end
     for il = 0 to 131071 v[il] = 0;
     for each Rl[linl,coll] begin
        rl = Rl[linl,coll];
        if (hnl == 1) then begin
           if (rl <> nvl) then begin
              il = rl - roffl; v[il] = v[il] + 1;
           end
        end
        if (hnl == 0) then begin
           il = rl - roffl; v[il] = v[il] + 1;
        end
     end
     suml = v[0]; flagl = 0;
     for il=1 to 131071 begin
        if (flagl == 0) then begin
           suml = suml + v[il]; cfql = suml * 100 / countl;
           if (cfql >= ptilel) then begin
              flagl = 1; funcval = il + roffl;
           end
        end
     end
     return (funcval);
  end
# ------------------------------------------------------------
# DEFINE func expPower(dnLl,dnMl,dnHl):
  func expPower(dnLl,dnMl,dnHl) begin
     local numeric delLHl,delLMl,sr1l,sr2l,exppl;
     sr1l = 0.3; sr2l = 2 * (1 - sr1l);
     delLHl = dnHl - dnLl; delLMl = dnMl - dnLl;
     exppl = sr1l + sr2l * delLMl / delLHl;
     return (exppl);
  end
# ------------------------------------------------------------
# DEFINE proc checkHisto(Band)
# PURPOSE: Check that Input Raster has a Full (Unsampled)
#          Histogram.  If Not, Then Recompute Histogram.
  proc checkHisto (raster Band) begin
     local numeric sampleInt;
     sampleInt = HistogramGetSampleInterval(Band);
     if (sampleInt > 1) begin
        DeleteHistogram(Band); CreateHistogram(Band,0);
     end
     else if (sampleInt == -1) then	begin
        CreateHistogram(Band,0);
     end
  end
# ------------------------------------------------------------
# ASSIGN VALUES TO GRUVI DATATYPE, SCALE & RANGE PARAMETERS:
  gtype$ = "16-bit signed";
  grumax = 3000; gruvirange = 1000; grunull = -grumax - 1;
# ------------------------------------------------------------
# WRITE TITLE & AUTHOR INFORMATION:
  writeTitle(pVI);
# ------------------------------------------------------------
# ASK USER TO NAME FOREGROUND & BACKGROUND MATERIALS:
  if (pVI == 1) then begin
     printf("GRUVI RELATES TO FOREGROUND VEGETATION");
     printf(" CONTRASTED AGAINST\nA BACKGROUND OF ");
     printf("BARE SOILS, RESIDUE, OR WATER.\n\n");
  end
  else begin
     t$  = "IDENTIFY FOREGROUND MATERIALS";
     p$ = "FOREGROUND-MATERIALS NAME?";
     fore$ = PopupString(p$,"ENTER NAME",t$);
     printf("  GRUFI RELATES TO: ");
     printf("%s\n",fore$);
     t$  = "IDENTIFY BACKGROUND MATERIALS";
     p$ = "BACKGROUND-MATERIALS NAME?";
     back$ = PopupString(p$,"ENTER NAME",t$);
     printf("CONTRASTED AGAINST: ");
     printf("%s\n\n",back$);
  end
# ------------------------------------------------------------
# ASK USER TO SELECT TRANSFORMATION OPTION:
  if (pVI == 2) then begin
     tsrfi = 1;
  end
  else begin
     p1$ = "SRFI TRANSFORMATION OPTION:\n";
     p2$ = "   For Classic NDVI, SAVI, or PVI: CLICK  NO\n";
     p3$ = "   For Transformed NDVI or  TSAVI: CLICK YES\n";
     p4$ = "             For CUSTOMIZED GRUVI: CLICK YES\n";
     p5$ = "CLICK YES or NO:";
     p$ = p1$ + p2$ + p3$ + p4$ + p5$;
     tsrfi = PopupYesNo(p$,1);
  end
# ------------------------------------------------------------
# ASK USER TO DEFINE FOREGROUND-MATERIALS POINT IN 2-SPACE:
# srfiXv = SRFI VALUE for FOREGROUND MATERIALS.
  if (pVI == 1) then begin
     p1$ = "X-AXIS DENSE-VEGETATION POINT:\n";
     p2$ = "   DEFAULT: 300\n";
     p3$ = "VALUE ENTERED:";
     p$ = p1$ + p2$ + p3$;
     srfiXv = PopupNum(p$,300,-32000,32000,0);
#    srfiYv = SRFIY VALUE for FOREGROUND MATERIALS.
     p1$ = "Y-AXIS DENSE-VEGETATION POINT:\n";
     p2$ = "   DEFAULT: 6000\n";
     p3$ = "VALUE ENTERED:";
     p$ = p1$ + p2$ + p3$;
     srfiYv = PopupNum(p$,6000,-32000,32000,0);
  end
  else begin
     p1$ = "X-AXIS FOREGROUND-MATERIALS POINT:\n";
     p2$ = "   DEFAULT: 300\n";
     p3$ = "VALUE ENTERED:";
     p$ = p1$ + p2$ + p3$;
     srfiXv = PopupNum(p$,300,-32000,32000,0);
#    srfiYv = SRFIY VALUE for FOREGROUND MATERIALS.
     p1$ = "Y-AXIS FOREGROUND-MATERIALS POINT:\n";
     p2$ = "   DEFAULT: 6000\n";
     p3$ = "VALUE ENTERED:";
     p$ = p1$ + p2$ + p3$;
     srfiYv = PopupNum(p$,6000,-32000,32000,0);
  end 
  if (tsrfi == 1) then begin
#    ASK USER TO DEFINE SLOPE OF LBM:
#    LBM is the LINE OF BACKGROUND MATERIALS.
     p1$ = "SLOPE OF LINE-OF-BACKGROUND-MATERIALS:\n";
     p2$ = "VALUE ENTERED:";
     p$ = p1$ + p2$;
     slope = PopupNum(p$,1.086,-100,100,4);
#    ASK USER TO DEFINE BACKGROUND-MATERIALS POINT IN 2-SPACE:
#    srfiXb = SRFIX VALUE for BACKGROUND MATERIALS.
     p1$ = "X-AXIS BACKGROUND-MATERIALS POINT:\n";
     p2$ = "VALUE ENTERED:\n";
     p$ = p1$ + p2$;
     srfiXb = PopupNum(p$,1711,-32000,32000,0);
#    srfiYb = SRFI VALUE for BACKGROUND MATERIALS.
     p1$ = "Y-AXIS BACKGROUND-MATERIALS POINT:\n";
     p2$ = "VALUE ENTERED:";
     p$ = p1$ + p2$;
     srfiYb = PopupNum(p$,2132,-32000,32000,0);
     srfiXorg = 0;
#    IF pVI == 2, ASK USER TO DEFINE NEW X ORIGIN IN 2-SPACE:
#    Xorg = SRFIX VALUE for NEW ORIGIN.
#    Corresponding Yorg is CALCULATED -- not Specified.
     if (pVI == 2) then begin
        p1$ = "LINE-OF-BACKGROUND-MATERIALS X ORIGIN:\n";
        p2$ = "VALUE ENTERED:";
        p$ = p1$ + p2$;
        srfiXorg = PopupNum(p$,0,-32000,32000,0);
     end
#    CALCULATED srfiYorg VALUE:  
     srfiYorg = round(srfiYb - slope * (srfiXb - srfiXorg));
  end
  else begin
     srfiXorg = 0; srfiYorg = 0; slope = 1;
  end
# ------------------------------------------------------------
# ASK USER TO OPT FOR OPTIMIZING THE bnp PARAMETER:
# IF NOT OPTIMIZED, THEN USER MUST SPECIFY THE VALUE OF bnp.
  p1$ = "BACKGROUND NOISE PARAMETER (bnp) OPTIMIZATION:\n";
  p2$ = "Are You USING a TEST AREA for bnp OPTIMIZATION?\n";
  p$ = p1$ + p2$;
  bnpop = PopupYesNo(p$,0);
  if (bnpop == 1) then begin
#    START OPTIMIZATION PROCESS LEADING TO bnp:
     gcv1 = 1000; gflag = 0;
     GetInputRaster(SRFIXT);
     nlins = NumLins(SRFIXT); ncols = NumCols(SRFIXT);
     rtype$ = RastType(SRFIXT);
     checkHisto(SRFIXT);
     GetInputRaster(SRFIYT,nlins,ncols,rtype$);
     checkHisto(SRFIYT);
     rang = -atan(slope);
     rangdeg = rang * deg; rangdeg = rangdeg + 45;
     printf("   CCW ROTATION ANGLE: %6.2f deg\n\n",rangdeg);    
     sinrang = sind(rangdeg); cosrang = cosd(rangdeg);
#    TRANSLATION TO A NEW ORIGIN:
     tsrfiX1 = srfiXv - srfiXorg;
     tsrfiY1 = srfiYv - srfiYorg;
#    SCALE-PRESERVING ROTATION:
     tsrfiX2 = tsrfiX1 * cosrang - tsrfiY1 * sinrang;
     tsrfiY2 = tsrfiX1 * sinrang + tsrfiY1 * cosrang;
     dbnpf = 0.02; bnpf = 0.00;
     CreateTempRaster(GRUVIT,nlins,ncols,gtype$,0);
     IgnoreNull(GRUVIT);
     for i = 0 to 1000 step 1 begin
        if (gflag == 0) then begin
           bnpf = bnpf + dbnpf;
           bnpi = bnpf * 5000;
           tsrfiX3 = tsrfiX2 + bnpi;
           tsrfiY3 = tsrfiY2 + bnpi;
           gruvidveg = (tsrfiY3 - tsrfiX3);
           gruvidveg = gruvidveg / (tsrfiY3 + tsrfiX3); 
           gfac = gruvirange / gruvidveg;
           for each GRUVIT begin
              GRUVIT = grunull;
              isnull = IsNull(SRFIXT);
              if (isnull == 0) then begin
                 srfiX = SRFIXT;
                 srfiY = SRFIYT;
                 tsrfiX4 = srfiX - srfiXorg;
                 tsrfiY4 = srfiY - srfiYorg;
                 tsrfiX5 = tsrfiX4 * cosrang - tsrfiY4 * sinrang;
                 tsrfiY5 = tsrfiX4 * sinrang + tsrfiY4 * cosrang;
                 tsrfiX6 = tsrfiX5 + bnpi;
                 tsrfiY6 = tsrfiY5 + bnpi;
                 gruvif = tsrfiY6 - tsrfiX6;
                 gruvif = gfac * gruvif / (tsrfiY6 + tsrfiX6);
                 gruvi = round(gruvif);
                 if (gruvi < -grumax) then gruvi = -grumax;
                 if (gruvi > grumax) then gruvi = grumax;
                 GRUVIT = gruvi;
              end
           end
           SetNull(GRUVIT,grunull);
           gmean = GlobalMean(GRUVIT);
           gmean = gmean - 1000;
           gstd = GlobalSD(GRUVIT);
           gcv2 = gstd * 100 / gmean;
           if (gcv2 < gcv1) then begin
              gcv1 = gcv2;
           end
           else begin
              bnp = bnpf - dbnpf;
              gflag = 1;
           end
           IgnoreNull(GRUVIT);
        end
     end
     CloseRaster(GRUVIT);
     CloseRaster(SRFIXT); CloseRaster(SRFIYT);
     printf("   OPTIMIZED bnp VALUE: %5.2f\n\n",bnp);
  end
  else bnp = 0.5;
# ASK USER TO SPECIFY THE VALUE OF bnp:
  if (tsrfi == 1) then begin
     p1$ = "BACKGROUND-NOISE PARAMETER (bnp) FOR\n";
     p2$ = "TRANSFORMED INDICES ONLY:\n";
     p3$ = "   RANGE: 0.02 to 20.00\n";
     p4$ = "   Classic    TSAVI: bnp  =  0.15\n";
     p5$ = "   Classic     WDVI: bnp  = 20.00\n";
     p6$ = "   Customized INDEX: 0.00 < bnp < 20.00\n";
     p7$ = "ENTER bnp VALUE:\n";
     p$ = p1$ + p2$ + p3$ + p4$ + p5$ + p6$ + p7$;
     bnp = PopupNum(p$,bnp,0.02,20.00,2);
  end
  else begin
     p1$ = "BACKGROUND-NOISE PARAMETER (BNP) FOR\n";
     p2$ = "NON-TRANSFORMED INDICES ONLY:\n";
     p3$ = "   RANGE: 0.0 to 20.00\n";
     p4$ = "   Classic     NDVI: bnp  =  0.00\n";
     p5$ = "   Classic     SAVI: bnp  =  0.50\n";
     p6$ = "   Classic      PVI: bnp  = 20.00\n";
     p7$ = "ENTER bnp VALUE:\n";
     p$ = p1$ + p2$ + p3$ + p4$ + p5$ + p6$ + p7$;
     bnp = PopupNum(p$,bnp,0.0,20.00,2);
  end
  printf("   LINE OF BACKGROUND MATERIALS:\n");
  printf("      srfiYb = %7.1f +",srfiYorg);
  printf(" %7.4f * (srfiXb ",slope);
  if (srfiXorg>=0) then begin
     printf("- %6d)\n\n",srfiXorg);
  end
  else begin
     printf("+ %6d)\n\n",-srfiXorg);
  end
  printf("   SELECTED bnp VALUE: %5.2f\n\n",bnp);
  if (pVI == 1) then begin
     printf("   DENSE-VEGETATION POINT:\n");
     printf("      srfiXveg = %6d\n",srfiXv);
     printf("      srfiYveg = %6d\n\n",srfiYv);
  end
  else begin
     printf("   FOREGROUND-MATERIALS POINT:\n");
     printf("      srfiXfore = %6d\n",srfiXv);
     printf("      srfiYfore = %6d\n\n",srfiYv);
  end
  cvi = 1;
  if (pVI == 1) then begin
     if (tsrfi == 0) then begin
        if (abs(bnp) < 0.02) then begin
           printf("   RESULT: Classic NDVI\n");
           cvi = 0;
        end
        if (abs(bnp - 0.5) < 0.02) then begin
           printf("   RESULT: Classic SAVI\n");
           cvi = 0;
        end
        if (abs(bnp - 20) < 0.02) then begin
           printf("   RESULT: Classic PVI\n");
           cvi = 0;
        end
     end
     if (tsrfi == 1) then begin
        if (abs(bnp) < 0.02) then begin
           printf("   RESULT: Transformed NDVI\n");
           cvi = 0;
        end
        if (abs(bnp - 0.15) < 0.02) then begin
           printf("   RESULT: Classic TSAVI\n");
           cvi = 0;
        end
        if (abs(bnp - 20) < 0.02) then begin
           printf("   RESULT: Classic WDVI\n");
           cvi = 0;
        end
     end
     if (cvi == 1) then begin
        printf("   RESULT: Customized GRUVI\n");
     end
  end
  else begin
     printf("   RESULT: Customized GRUFI\n");
  end
  if (bnp < 0.01) then bnp = 0.01;
  bnpxy = bnp * 5000;
# ------------------------------------------------------------
# PERFORM TRANSLATION (T) & ROTATION (R) TRANSFORMATION
# TO CALCULATE GRUVI SCALE-CHANGE FACTOR, gfac:
  rang = -atan(slope);
  rangdeg = rang * deg; rangdeg = rangdeg + 45;
  sinrang = sind(rangdeg); cosrang = cosd(rangdeg);
  tsrfiX1 = srfiXv - srfiXorg;
  tsrfiY1 = srfiYv - srfiYorg;
  tsrfiX2 = tsrfiX1 * cosrang - tsrfiY1 * sinrang;
  tsrfiY2 = tsrfiX1 * sinrang + tsrfiY1 * cosrang;
  tsrfiX2 = tsrfiX2 + bnpxy;
  tsrfiY2 = tsrfiY2 + bnpxy;
  gruvidveg = (tsrfiY2 - tsrfiX2) / (tsrfiY2 + tsrfiX2); 
  gfac = gruvirange / gruvidveg;
  grubif = (bnpxy + srfiXorg) * (bnpxy + srfiXorg);
  grubif = grubif + (bnpxy + srfiYorg) * (bnpxy + srfiYorg);
  grubifmin = sqrt(grubif);
# ------------------------------------------------------------
# ASK USER TO GET INPUT RASTERS CALLED SRFIX & SRFIY:
  GetInputRaster(SRFIX);
  nlins = NumLins(SRFIX); ncols = NumCols(SRFIX);
  rtype$ = RastType(SRFIX);
  checkHisto(SRFIX);
  GetInputRaster(SRFIY,nlins,ncols,rtype$);
  checkHisto(SRFIY);
# ------------------------------------------------------------
# ASK USER TO DESIGNATE OUTPUT GRUVI & GRUBI RASTERS:
  GetOutputRaster(GRUBI,nlins,ncols,gtype$);
  printf("\nPROCESSING ACTIONS:\n");
  printf("Assigning GRUBI Values to Null Value.\n");
  GRUBI = grunull;
  SetNull(GRUBI,grunull);
  CopySubobjects(SRFIX,GRUBI,"GEOREF");
  if (pVI == 1) then begin
     GetOutputRaster(GRUVI,nlins,ncols,gtype$);
     printf("Assigning GRUVI Values to Null Value.\n");
     GRUVI = grunull;
     SetNull(GRUVI,grunull);
     CopySubobjects(SRFIX,GRUVI,"GEOREF");
  end
  else begin
     GetOutputRaster(GRUFI,nlins,ncols,gtype$);
     printf("Assigning GRUFI Values to Null Value.\n");
     GRUFI = grunull;
     SetNull(GRUFI,grunull);
     CopySubobjects(SRFIX,GRUFI,"GEOREF");
  end
  printf("Producing Output Rasters.\n");
  for each SRFIX begin
     isnull = IsNull(SRFIX);
     if (isnull == 0) then begin
        srfiX = SRFIX;
        srfiY = SRFIY;
        tsrfiX1 = srfiX - srfiXorg;
        tsrfiY1 = srfiY - srfiYorg;
        tsrfiX2 = tsrfiX1 * cosrang - tsrfiY1 * sinrang;
        tsrfiY2 = tsrfiX1 * sinrang + tsrfiY1 * cosrang;
        tsrfiX2 = tsrfiX2 + bnpxy;
        tsrfiY2 = tsrfiY2 + bnpxy;
        grubif = tsrfiX2 * tsrfiX2;
        grubif = grubif + tsrfiY2 * tsrfiY2;
        grubif = sqrt(grubif) - grubifmin;
        grubi = round(0.2 * grubif);
        gruvif = tsrfiY2 - tsrfiX2;
        gruvif = gfac * gruvif / (tsrfiY2 + tsrfiX2);
        gruvi = round(gruvif);
        if (grubi < -grumax) then grubi = -grumax;
        if (grubi > grumax) then grubi = grumax;
        if (gruvi < -grumax) then gruvi = -grumax;
        if (gruvi > grumax) then gruvi = grumax;
        GRUBI = grubi;
        if (pVI == 1) then begin
           GRUVI = gruvi;
        end
        else begin
           GRUFI = gruvi;
        end
     end
  end
# ------------------------------------------------------------
# CREATE HISTOGRAMS & PYRAMIDS.  THEN, CLOSE RASTERS:
  printf("Adding Histogram & Pyramid Subobjects.\n");
  if (pVI == 1) then begin
     CreateHistogram(GRUVI,0); CreatePyramid(GRUVI,0);
     hnmGF = HasNullMask(GRUVI); hnGF = HasNull(GRUVI);
     if (hnGF == 1) then nvGF = NullValue(GRUVI);
     c1GF = GlobalPtile(GRUVI,0.5,hnGF,nvGF);
     c3GF = GlobalPtile(GRUVI,50,hnGF,nvGF);
     c2GF = GlobalPtile(GRUVI,99.5,hnGF,nvGF);
     pGF = expPower(c1GF,c3GF,c2GF);
     smlContrast.InputLowerLimit = c1GF;
     smlContrast.InputUpperLimit = c2GF;
     smlContrast.Power           =  pGF;
     smlContrast.Compute(GRUVI,clut1$,clut2$,clut3$);
     CloseRaster(GRUVI);
  end
  else begin
     CreateHistogram(GRUFI,0); CreatePyramid(GRUFI,0);
     hnmGF = HasNullMask(GRUFI); hnGF = HasNull(GRUFI);
     if (hnGF == 1) then nvGF = NullValue(GRUFI);
     c1GF = GlobalPtile(GRUFI,0.5,hnGF,nvGF);
     c3GF = GlobalPtile(GRUFI,50,hnGF,nvGF);
     c2GF = GlobalPtile(GRUFI,99.5,hnGF,nvGF);
     pGF = expPower(c1GF,c3GF,c2GF);
     smlContrast.InputLowerLimit = c1GF;
     smlContrast.InputUpperLimit = c2GF;
     smlContrast.Power           =  pGF;
     smlContrast.Compute(GRUFI,clut1$,clut2$,clut3$);
     CloseRaster(GRUFI);
  end
  CreateHistogram(GRUBI,0); CreatePyramid(GRUBI);
  hnmGB = HasNullMask(GRUBI); hnGB = HasNull(GRUBI);
  if (hnGB == 1) then nvGB = NullValue(GRUBI);
  c1GB = GlobalPtile(GRUBI,0.5,hnGB,nvGB);
  c3GB = GlobalPtile(GRUBI,50,hnGB,nvGB);
  c2GB = GlobalPtile(GRUBI,99.5,hnGB,nvGB);
  pGB = expPower(c1GB,c3GB,c2GB);
  smlContrast.InputLowerLimit = c1GB;
  smlContrast.InputUpperLimit = c2GB;
  smlContrast.Power           =  pGB;
  smlContrast.Compute(GRUBI,clut1$,clut2$,clut3$);
  CloseRaster(SRFIX); CloseRaster(SRFIY);
  CloseRaster(GRUBI);
  printf("Processing Finished.");
  printf("TO SAVE THE CONSOLE WINDOW TEXT AS A REPORT:\n");
  printf("   1. RIGHT-CLICK IN THE CONSOLE WINDOW.\n");
  printf("   2. SELECT THE Save As... OPTION.\n");
  printf("   3. NAVIGATE TO THE DESIRED LOCATION.\n");
  printf("   4. PROVIDE A REPORT NAME (or OVERWRITE).\n");
  printf("   5. CLICK OK.");